C#Xml反序列化+设计建议
在我的项目中,我需要构建一个应该向后兼容的通用反序列化程序。 示例:XML看起来像C#Xml反序列化+设计建议,c#,xml,xmlserializer,xml-deserialization,C#,Xml,Xmlserializer,Xml Deserialization,在我的项目中,我需要构建一个应该向后兼容的通用反序列化程序。 示例:XML看起来像 <PolicyDef name = "sample" type="type1"> <Options ......> </PolicyDef> PolicyDef类定义为 [XmlRoot("PolicyDef")] public class PolicyDef { private string policyName; pri
<PolicyDef name = "sample" type="type1">
<Options ......>
</PolicyDef>
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将抛出异常。
因此,如果我有像
<PolicyDef name = "sample" type="type_new">
<Options ......>
</PolicyDef>
反序列化程序将抛出错误,因为类型\u new无效
我想知道是否有一种方法可以钩住反序列化程序进程来捕获它,并设置一个默认值,而不是抛出错误。如果有任何无效值,我会将其设置为“type1”
或者我愿意接受关于如何处理这个问题的建议
感谢并问候这可能是 不幸的是,在反序列化过程中似乎没有办法依赖默认枚举值。这将需要稍多的工作,但如果您遵循链接的示例并在PolicyDef类中实现IXmlSerializable,您将能够以类似的方式实现ReadXml方法(使用try/catch块反映每个属性以检查默认值)
希望有帮助 谢谢Chris的建议,但我不想最终编写完整的解析代码,如果XML和相应的类是巨大而复杂的,那么这些代码可能会很混乱。无论如何,我使用了不同的方法。 我将所有枚举字段都更改为字符串。在这种情况下,将不会出现解析错误,然后公开另一个属性,该属性将以枚举的形式返回解析后的值,如果解析失败,则返回默认枚举值。例如
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属性字段
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;
}