I know that an enum
value can be deserialised from either a string or an integer value but not both. I want to write some code which handles an enum
deserialisation no matter the value in the XML is an integer or a string. An example is given below with sample data.
Data Strcuture
class Employee
{
public string Name { get; set; }
public RankType Rank { get; set; }
}
enum RankType
{
Junior,
MidLevel,
Senior,
Executive
}
Possible XML data - sample 1
<employee>
<name>John Doe</name>
<rank>Executive</rank>
</employee>
Possible XML data - sample 2
<employee>
<name>John Doe</name>
<rank>3</rank>
</employee>
I wrote this code which works fine for sample 1, but crashes for sample 2:
var xs = new XmlSerializer(typeof(Employee));
XmlDocument xml = new XmlDocument();
xml.LoadXml(empRequest);
var node = xml.SelectSingleNode("/EmpRequest"); // <-- the exact path here is irrelevant
var sr = new StringReader(xml.InnerXml);
var obj = (Employee)xs.Deserialize(sr); // <-- Exception here
The exception message is: " '3' is not a valid value for RankType "
You can either make your Employee
class IXmlSerializable
and fully control how it's serialized and deserialized.
Or you can prepare your xml document before you pass it to XmlSerializer
.
For example, search for all employee\rank
nodes and if they contain integer change it to name.
var xs = new XmlSerializer(typeof(Employee));
XmlDocument xml = new XmlDocument();
xml.LoadXml(empRequest);
// update employee/rank
foreach (XmlElement rankNode in xml.SelectNodes("//employee/rank"))
if (Int32.TryParse(rankNode.InnerText, out int rank) && Enum.IsDefined(typeof(RankType), rank))
rankNode.InnerText = Enum.GetName(typeof(RankType), rank);
// loading further
var node = xml.SelectSingleNode("/EmpRequest");
var sr = new StringReader(node.InnerXml);
var obj = (Employee)xs.Deserialize(sr);
The following will work with either the name or integer value
class Employee
{
public string Name { get; set; }
private RankType Rank { get; set; }
[XmlElement("Rank")]
public string _Rank {
get {
return Rank.ToString();
//use following if you want integer when serializing
//return ((int)Rank).ToString();
}
set
{
int number = 0;
Boolean numeric = int.TryParse(value, out number);
if (numeric)
{
Rank = (RankType)number;
}
else
{
Rank = (RankType)Enum.Parse(typeof(RankType), value);
}
}
}
enum RankType
{
Junior,
MidLevel,
Senior,
Executive
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.