4

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.

NeilD
  • 2,198
  • 2
  • 23
  • 28
  • http://stackoverflow.com/a/1266758/485076 – sll Oct 31 '12 at 14:22
  • You could try creating an XML object from your input string first, then iterate over the nodes and replace all empty values with ValueOne. – FLClover Oct 31 '12 at 14:23

2 Answers2

4

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

Pranay Rana
  • 170,430
  • 35
  • 234
  • 261
  • 4
    Hmm... That's a decent option, but it does require that I know all of the potential bad values ahead of time. I'd like something that will cope if they send "", or "ValueThree", or "SomethingTotallyRandom". – NeilD Oct 31 '12 at 14:32
0

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;
Anirudha
  • 31,626
  • 7
  • 66
  • 85