4

我有一個類,它看起來像這樣(嚴重簡化):XmlSerializer - 如何在反序列化枚舉時設置默認值?

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

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

我從外部源接收XML文件。他們的文檔指出,Foo元素在Bar屬性中只會有「ValueOne」或「ValueTwo」(它們不提供XSD)。

所以,我反序列化這樣的:

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

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

...這所有的作品。

然而,昨天晚上,他們給我一些XML看起來像這個,而是和我的反序列化失敗(因爲它應該):<Foo Bar="" />

有沒有好的辦法來防守代碼解決此問題?理想情況下,我想說一些類似於「缺省值ValueOne,如果出現問題的地方」。我不想扔掉整個XML文件,因爲一個屬性被破壞了。

+0

http://stackoverflow.com/a/1266758/485076 – sll

+0

你可以嘗試先建立從您的輸入字符串的XML對象,然後遍歷節點和全部替換爲空值與ValueOne。 – FLClover

回答

4

,您可以設置枚舉這樣的,所以這將設置「枚舉」值未知= 0有點像默認值

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

更詳細的檢查:XmlEnumAttribute Class

+2

嗯......這是一個不錯的選擇,但它確實需要我提前知道所有可能的錯誤值。如果他們發送「」,「ValueThree」或「SomethingTotallyRandom」,我希望能應付某些事情。 – NeilD

0

擊落XmlSerializer .. 使用LINQ2XML對於這個簡單的任務

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>(); 

所以,我基本上做這

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; 
+0

我認爲Foo類更大,作者試圖避免手動反序列化 –

+0

@DmitryDovgopoly仍然可以使用Linq2Xml ... – Anirudha

+0

是的,真正的XML和類結構是巨大的!重構所有與Linq2Xml一起工作將是一件很大的工作。 – NeilD