简体   繁体   English

使用c#中的Value属性从Xml反序列化枚举

[英]Deserialize Enum from Xml using Value property in c#

I am trying to write an ONIX for book import tool in C#. 我正在尝试用C#编写ONIX for book导入工具。 I started by creating the classes using Xsd2Code and got a huge file with all the properties which after a few tweaks does not produce any error upon deserializing. 我开始使用Xsd2Code创建类,并获得了一个包含所有属性的大文件,经过一些调整后,在反序列化时不会产生任何错误。

I am trying to deserialize an entire element in one go, into a big object in memory and then do stuff with it (such as save it to database). 我试图一次性将整个元素反序列化为内存中的一个大对象,然后用它做一些事情(比如将它保存到数据库中)。

The way the Xsd2Code generated the classes, apart from the fact that there are A LOT of properties, are a bit weird, at least to me. 除了有很多属性之外,Xsd2Code生成类的方式有点奇怪,至少对我而言。

Here's one of the classes which should be a property of the Product object: 这是应该是Product对象的属性的类之一:

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }

    public SourceTypeCode sourcetype { get; set; }

    public List1 Value { get; set; }
}

I would like to direct your attention to this line: 我想请你注意这一行:

    public List1 Value { get; set; }

"List1" is an enum, defined like so: “List1”是一个枚举,定义如下:

public enum List1
{
    [System.Xml.Serialization.XmlEnum("01")]
    Item01,

    [System.Xml.Serialization.XmlEnum("02")]
    Item02, etc...

My problem is that during deserialization, all fields deserialize correctly EXCEPT the Enums. 我的问题是在反序列化期间,所有字段都正确地反序列化除了枚举。

I tried decorating the properties with XmlEnum("NotificationType") etc... nothing! 我尝试使用XmlEnum(“NotificationType”)等来装饰属性......没有!

This is my deserialization code: 这是我的反序列化代码:

var p = new Product();
XmlSerializer pserializer = new XmlSerializer(p.GetType());
object pDeserialized = pserializer.Deserialize(reader);
p = (Product) pDeserialized;

This is how this element looks like in XML: 这是XML中这个元素的样子:

<NotificationType>03</NotificationType>

The property that is in C# for the Product object is: Product对象在C#中的属性是:

public NotificationType NotificationType { get; set; }

If I change this to: 如果我将其更改为:

public List1 NotificationType { get; set; }

the deserialization correctly shows 'Item03', meaning it does read whatever is in XML. 反序列化正确显示'Item03',这意味着它确实读取了XML中的任何内容。 IF I leave it like above, the 'Value' property of the NotificationType class is never filled, and always shows Item01 (the default of the Enum). 如果我像上面那样离开它,NotificationType类的'Value'属性永远不会被填充,并且始终显示Item01(Enum的默认值)。

I have exhausted all possible questions on SO and web searches as to WHY this Value property works with some types (Strings) but not Enums. 我已经用尽所有关于SO和网络搜索的问题,为什么这个Value属性适用于某些类型(字符串)但不适用于枚举。 Am I missing something? 我错过了什么吗?

Sorry for the long question and code. 很抱歉这个问题和代码很长。 Appreciate any light anyone can shed on this issue. 感谢任何人都可以解决这个问题。 Been stuck with it for a whole day now. 现在已经坚持了整整一天。

Try this: 试试这个:

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }
    public SourceTypeCode sourcetype { get; set; }

    public List1 Value { get {
        return (List1)Enum.Parse(typeof(List1), 
            Enum.GetName(typeof(List1), int.Parse(List1Value) - 1));
    }}

    [XmlText]
    public string List1Value { get; set; }
}

[UPDATE] [UPDATE]

Since: 以来:

  1. I also tried at first decorating the member with the XmlText attribute, but the following exception was occurring: 我还尝试首先使用XmlText属性装饰成员,但发生了以下异常:

    Cannot serialize object of type 'ConsoleApplication1.NotificationType'. 无法序列化“ConsoleApplication1.NotificationType”类型的对象。 Consider changing type of XmlText member 'ConsoleApplication1.NotificationType.Value' from ConsoleApplication1.List1 to string or string array. 考虑将ConsoleApplication1.List1中的XmlText成员'ConsoleApplication1.NotificationType.Value'的类型更改为字符串或字符串数​​组。

  2. and you would like to avoid my initial approach in the answer, 你想避免我在答案中的初步方法,

the real solution is that, besides applying the XmlText attribute to Value , all the other members should be decorated with the XmlIgnoreAttribute . 真正的解决方案是,除了将XmlText属性应用于Value ,所有其他成员都应该使用XmlIgnoreAttribute进行修饰。 I believe that using XmlText alone is not a guaranteed solution, as the results depend on the existence of other members. 我相信单独使用XmlText不是一个有保证的解决方案,因为结果取决于其他成员的存在。

public class NotificationType
{
    [XmlIgnore] // required
    public NotificationTypeRefname refname { get; set; }
    [XmlIgnore] // required
    public NotificationTypeShortname shortname { get; set; }
    [XmlIgnore] // required
    public SourceTypeCode sourcetype { get; set; }

    [XmlText] // required
    public List1 Value { get; set; }
}

Try adding [System.Xml.Serialization.XmlTextAttribute()] to the public List1 Value { get; set; } 尝试将[System.Xml.Serialization.XmlTextAttribute()]添加到public List1 Value { get; set; } public List1 Value { get; set; } public List1 Value { get; set; } property. public List1 Value { get; set; }属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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