C# 如何反序列化没有null值的复杂XML元素? 一些价值 一些价值
我有上面的xml,Address元素是一个复杂的对象。当我试图反序列化到C#object时,address对象中的所有属性都设置为null,但我的要求是将address对象本身设置为null。有没有办法做到这一点?您可以使用XmlIgnore属性排除对象的属性C# 如何反序列化没有null值的复杂XML元素? 一些价值 一些价值,c#,xml,serialization,C#,Xml,Serialization,我有上面的xml,Address元素是一个复杂的对象。当我试图反序列化到C#object时,address对象中的所有属性都设置为null,但我的要求是将address对象本身设置为null。有没有办法做到这一点?您可以使用XmlIgnore属性排除对象的属性 <Customer> <FirstName>SomeValue</FirstName> <LastName>Somevalue</LastName> <Address/&g
<Customer>
<FirstName>SomeValue</FirstName>
<LastName>Somevalue</LastName>
<Address/>
</Customer>
为了确认您的问题,您会问:在反序列化XML时,我是否可以将空元素映射到
null
属性值,而将非空元素映射到非null
属性值?
假设您正在使用,这不是开箱即用的实现<当属性(通常缩写为xsi:nil
)具有值“true”
时,code>XmlSerializer仅将元素映射到null
值。发件人:
XmlSerializer类将nil属性的真值与空引用相等,执行以下运行时转换:
- 将XML文档反序列化为对象时:如果XmlSerializer类遇到指定xsi:nil=“true”的XML元素,它将为相应的对象分配一个空引用(如果适用)
- 将对象序列化到XML文档中时:如果XmlSerializer类遇到对应于XML元素的对象的空引用,它会生成指定xsi:nil=“true”的元素,或者完全忽略该元素,具体取决于是否应用nillable=“true”设置
xsi:nil
不存在于空的
元素中,因此它不会自动映射到null
作为一种解决方法,您可以将地址
的额外“代理”属性引入客户
中,在反序列化过程中,该属性检查要设置的地址
是否具有默认值,如果是,则将基础地址值设置为null
。例如,如果您的类看起来像:
[XmlIgnore]
public Address {get; set;}
您可以通过以下两种方式完成此操作:
public class Address
{
public string Street1 { get; set; }
public string Street2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
属性SerializableAddress
使用反射检查传入的地址是否有任何非默认值。如果不是,则基础属性设置为null
这个解决方案是健壮的和可重用的,但是由于它使用反射,所以性能可能不是很好
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
[XmlIgnore]
public Address Address { get; set; }
[XmlElement("Address")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public Address SerializableAddress
{
get
{
return Address;
}
set
{
if (value != null && value.MembersAreDefault())
value = null;
Address = value;
}
}
}
接下来,为地址实现该接口:
public interface IHasDefaultMemberValues
{
bool MembersAreDefault();
}
最后,按照与解决方案1相同的方式修改客户
此解决方案是有效的,但取决于在将新属性添加到客户时正确维护成员redefault()
您能否为您的
客户
和地址
类共享c?请包括一个。谢谢DBC。但在反序列化字符串之前,我使用正则表达式从字符串中删除空节点,它对我有效。
public interface IHasDefaultMemberValues
{
bool MembersAreDefault();
}
public class Address : IHasDefaultMemberValues
{
// Properties as above.
#region IHasDefaultMemberValues Members
public virtual bool MembersAreDefault()
{
return Street1 == null && Street2 == null && City == null && State == null && Zip == null && Country == null;
}
#endregion
}