枚举的序列化失败

时间:2012-02-10 10:35:12

标签: c# enums xml-serialization

我使用.NET 3.5。

我有一个枚举:

[System.SerializableAttribute()]
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

我在课堂上使用这个枚举:

[System.SerializableAttribute()]
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public MyEnum MyEnum { get; set; }
}

现在我想创建一个新的Eplomyee实例,通过从字符串中转换它来设置MyEnum属性。 然后序列化并将其保存在文件中。

Employee bob = new Employee() {Id = 1, Name = "Bob"};
bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035"));

XmlSerializer serializer = new XmlSerializer(typeof(Employee));
FileInfo fi = new FileInfo(@"C:\myfile.xml");
using (FileStream stream = fi.OpenWrite())
{
    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, OmitXmlDeclaration = true, Indent = true };
    using (XmlWriter writer = XmlWriter.Create(stream, xmlWriterSettings))
    {
        serializer.Serialize(writer, bob); // this is place where it goes wrong
    }
}

如果我调试这个,我发现bob.MyEnum的值 35

当我尝试序列化时,我得到一个例外:

  

生成XML文档时出错。

     

实例验证错误:'35'不是有效值   WindowsFormsApplication.MyEnum。

出了什么问题,我该如何解决?

3 个答案:

答案 0 :(得分:3)

这种情况正在发生,因为Enums在内部存储为int。因此,您的语句bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035"));正在运行而没有问题。如果您进行调试,bob.MyEnum的值为35。反序列化时,反序列化器会搜索匹配的enum,其中int值为35,而不存在,因为您指定了Item1和Item2。因此,您会收到错误。

这将有效

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "35");

 public enum MyEnum {
   Item1 = 35,
   Item2
 }

理想情况下你应该这样做

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "Single");

 public enum MyEnum {
   [System.Xml.Serialization.XmlEnumAttribute("Single")]
   Item1,
   Item2
 }

希望这会对你有所帮助。

答案 1 :(得分:3)

让我们开始吧:

[System.SerializableAttribute()] // useless, valuetype is implicitly so
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

现在XmlEnumAttribute控制如何在XML中序列化和反序列化该值。

它没有使用你的代码!(对不起,但是其他人似乎没有这个。)

因此,当MyEnum.Item1的值被序列化时,将发出“035”。

现在问题是你想要如何分配它。

很简单。就像你通常那样分配。没有这些属性改变了普通代码的语义,一切都保持不变。

示例:

Employee bob = new Employee() {Id = 1, Name = "Bob", MyEnum = MyEnum.Item1};

绝对没有理由在这里考虑Enum.Parse。枚举类型和值是静态已知的。

如果您确实想使用Enum.Parse,请像平常一样使用它,例如:

Enum.Parse(typeof(MyEnum), "Item1")

答案 2 :(得分:0)

我改变了枚举解析。

我使用反射将字符串解析为枚举,如本文所述:http://www.codeguru.com/csharp/csharp/cs_syntax/enumerations/article.php/c5869

现在它有效。

相关问题