【发布时间】:2012-10-10 13:16:27
【问题描述】:
我已经阅读了许多关于可空字段反序列化的帖子,但没有遇到以下情况:
- 序列化具有包含值的可为空字段的对象(“nil”属性未添加到节点,因为它包含值)。
- 从 xml 中的可为空字段中删除值(这通过客户端处理发生)。
- 反序列化 xml。
第 3 步会引发错误,因为序列化程序不会将可空字段的空值视为空值(因为未指定“nil=true”)。相反,它会尝试将值转换为字段的数据类型(例如:Guid),但失败会导致错误消息因字段的数据类型而异。
在 Guid 的情况下,错误消息是:
System.InvalidOperationException: There is an error in XML document ([line number], [column number]). ---> System.FormatException: Unrecognized Guid format.
我要注意的是,我们使用的序列化/反序列化方法是使用泛型的框架方法。
我正在寻找一种优雅而通用的解决方案。我能想到的唯一可行的通用解决方案如下:
- 将 xml 转换为 XDocument。
- 使用(低于预期的)反射来获取对象的所有引用类型的属性。
- 将“nil=true”属性添加到名称在 #2 的列表中找到的所有节点并且具有空值。
- 使用递归处理 #2 中的每个引用类型。
注意:简单地将“nil=true”添加到所有具有空值的节点将不起作用,因为序列化程序会为不能为空的值类型抛出错误。
[编辑]代码示例:
示例数据类
public class DummyData
{
public Guid? NullableGuid { get; set; }
}
Xml 发送给客户端
<DummyData>
<NullableGuid>052ec82c-7322-4745-9ac1-20cc4e0f142d</NullableGuid>
</DummyData>
从客户端返回的Xml(错误)
<DummyData>
<NullableGuid></NullableGuid>
</DummyData>
从客户端返回的Xml(期望的结果)
<DummyData>
<NullableGuid p2:nil="true" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance"></NullableGuid>
</DummyData>
【问题讨论】:
-
你能把数据对象的
Guid属性改成可以为空的Guid?类型吗?编辑:在设置器中,如果传递了null值,您可以将任何默认值Guid(我猜是Guid.Empty)分配给支持字段。 -
我所描述的场景实际上是使用一个可为空的 Guid 类型。问题是如果没有 nil="true",序列化程序会认为空值是有效的 Guid,而不是空值。指定“nil=true”时,反序列化空值可以正常工作。
-
如果值为空,是否应该由您的客户端应用程序将 nil=true 属性添加到 xml 中?在将数据发送到服务器之前,您使用什么来序列化数据?
-
期望每个脚本编写者都处理这种情况会非常麻烦。此外,客户端不知道节点是引用类型还是值类型。将“nil=true”添加到值类型也会导致错误,因为值类型不能为空(如帖子末尾所述)。
标签: c# xml field deserialization nullable