C# Xml Deserialize plus design suggestions

断了今生、忘了曾经 提交于 2019-12-13 02:59:38

问题


In my project I need to build a generic deserializer that should be backward compatible. Example: The XML looks like

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

The "type" is enum - PolicyTypes e.g

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

The PolicyDef class is defined as

[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;

            }
        }           
    }

The Problem with this approach is that if later on I put any type other than type 1 or type 2, the XMLDeserializer will throw exception. so if i have the xml like

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

The deserializer will throw error as type_new not valid.

I was wondering if there is a way to hook into the deserializer process to catch that and set a default value rather than throw error. Say if there is any invalid value, then I would set that to "type1"

Or am open to suggestions regarding how to handle this problem

Thanks and Regards


回答1:


This is possibly a duplicate of C# XML Deserialization W/ Default Values

Unfortunately it seems there is no way to fall back on default enum values during deserialisation. It will require slightly more work, but if you follow the linked example and implement IXmlSerializable in your PolicyDef class, you'll be able to implement the ReadXml method in a similar way (reflecting each of the properties using a try/catch block in order to check for a default value).

Hope that helps!




回答2:


Thanks Chris for the suggestion, but I don't want end up writing the complete parsing code which could be messy if the XML and corresponding class is huge and complex. I anyway used a different approach. I changed all the enum fields to string. In this case there would be no parsing error and then expose another property that would return the parsed value as enum and if the parsing fails, then return default enum value. 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;
}

And use the class property to access the value rather than the xml attribute field.



来源:https://stackoverflow.com/questions/14768052/c-sharp-xml-deserialize-plus-design-suggestions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!