C#Xml反序列化加上设计建议

本文关键字:反序列化 C#Xml | 更新日期: 2023-09-27 17:58:22

在我的项目中,我需要构建一个应该向后兼容的通用反序列化程序。示例:XML看起来像

<PolicyDef name = "sample" type="type1">
  <Options ......>
</PolicyDef>

"类型"是enum-PolicyTypes例如

public Enum PolicyTypes
{
 type1 = 0,
 type2 = 1
}

PolicyDef类定义为

[XmlRoot("PolicyDef")]
    public class PolicyDef
    {
        private string policyName;
        private PolicyTypes policyType;
        public PolicyDefinition()
        {         
        }
        [XmlAttribute]
        public string Name
        {
            get
            {
                return this.policyName;
            }
            set
            {
               this.policyName = value;
            }
        }      
        [XmlAttribute]
        public PolicyTypes Type
        {
            get
            {
                return this.policyType;
            }
            set
            {
               this.policyType = value;
            }
        }           
    }

这种方法的问题是,如果以后我放入类型1或类型2以外的任何类型,XMLDeserializer将抛出异常。所以如果我有类似xml的

<PolicyDef name = "sample" type="type_new">
  <Options ......>
</PolicyDef>

由于type_new无效,反序列化程序将引发错误。

我想知道是否有一种方法可以挂接到反序列化程序进程中,以捕获它并设置默认值,而不是抛出错误。假设有任何无效值,那么我会将其设置为"type1"

或者我愿意接受关于如何处理这个问题的建议

感谢和问候

C#Xml反序列化加上设计建议

这可能是C#XML反序列化W/默认值的重复

不幸的是,在取消序列化期间,似乎没有办法回到默认枚举值。这将需要更多的工作,但如果您遵循链接的示例并在PolicyDef类中实现IXmlSerializable,您将能够以类似的方式实现ReadXml方法(使用try/catch块来反映每个属性,以便检查默认值)。

希望能有所帮助!

感谢Chris的建议,但我不想最终编写完整的解析代码,如果XML和相应的类庞大而复杂,这可能会很混乱。无论如何,我使用了一种不同的方法。我将所有枚举字段都更改为字符串。在这种情况下,将不会出现解析错误,然后公开另一个属性,该属性将以枚举形式返回解析后的值,如果解析失败,则返回默认枚举值。E.g

private string policyName;
[XmlAttribute("Type")]
public string Type
{
    private get
    {
        return this.policyType;
    }
    set
    {
        this.policyType = value;
        try
        {
            this.PolicyType = (PolicyTypes)Enum.Parse(typeof(PolicyTypes), this.policyType);
        }
        catch(Exception)
        {
            this.PolicyType = PolicyTypes.DefaultPolicy;
        }
    }
}
public PolicyTypes PolicyType
{
    get;
    private set;
}

并使用class属性来访问值,而不是xml属性字段。