简体   繁体   中英

XmlSerializer - How can I set a default when deserializing an enum?

I have a class that looks like this (heavily simplified):

public class Foo
{
    public enum Value
    {
        ValueOne,
        ValueTwo
    }

    [XmlAttribute]
    public Value Bar { get; set; }
}

I'm receiving an XML file from an external source. Their documentation states that the Foo element will only ever have "ValueOne" or "ValueTwo" in the Bar attribute (they don't supply an XSD).

So, I deserialize it like this:

 var serializer = new XmlSerializer(typeof(Foo));
 var xml = "<Foo Bar=\"ValueTwo\" />";
 var reader = new StringReader(xml);

 var foo = (Foo)serializer.Deserialize(reader);

... and that all works.

However, last night, they sent me some XML looking like this instead, and my deserialization failed (as it should): <Foo Bar="" />

Is there a good way to defensively code around this? Ideally I'd like to say something like "default to ValueOne, if something goes wrong here". I don't want to throw away the whole XML file, because a single attribute was mangled.

you can set you enum like this , so this will set "" value of enum to Unknown = 0 somewhat like default value

public enum Foo
{
   [XmlEnum(Name = "")]
   Unknown =0,
   [XmlEnum(Name = "Single")]
   One,
   [XmlEnum(Name = "Double")]
   Two   
}

more detail check : XmlEnumAttribute Class

Shoot down XmlSerializer .. Use LINQ2XML for this simple task

XElement doc=XElement.Load("yourStreamXML"); 

List<Foo> yourList=doc.Descendants("Foo")
.Select(x=>
new Foo
{
    Bar=(Enum.GetNames(typeof(Value)).Contains(x.Attribute("Bar").Value))?((this.Value)x.Attribute("Bar")):(this.Value.ValueOne);
}
).ToList<Foo>();

So,I am basically doing this

if(Enum.GetNames(typeof(Value)).Contains(x.Attribute("Bar").Value))
//if the xml bar value is a valid enum
    Bar=(this.Value)x.Attribute("Bar");
else//xml bar value is not a valid enum..so use the default enum i.eValueOne
    Bar=this.Value.ValueOne;

You can manually parse enum value by creating another property with the same XmlAttribute name:

public enum Value
{
    // Default for unknown value
    Unknown,
    ValueOne,
    ValueTwo
}

[XmlIgnore]
public Value Bar { get; set; }

[XmlAttribute("Bar")]
public string _Bar
{
    get { return this.Bar.ToString(); }
    set { this.Bar = Enum.TryParse(value, out Value enumValue) ? enumValue : Value.Unknown; }
}

Usage the same as your before

var serializer = new XmlSerializer(typeof(Foo));
var xml = "<Foo Bar=\"invalid value\" />";
var reader = new StringReader(xml);
var foo = (Foo)serializer.Deserialize(reader);

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM