当null值时,Xsd.exe生成的类不会序列化必需元素

时间:2015-04-24 07:16:04

标签: .net xmlserializer xsd.exe

在以下XSD中,所有元素都是必需的:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://TestNamespace" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://TestNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Test">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
        <xs:element minOccurs="1" maxOccurs="1" name="EMail" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

但是,当我序列化xsd.exe生成的类的实例EMail == null时,生成的XML根据模式无效,因为EMail元素完全丢失。

<?xml version="1.0"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TestNamespace">
  <Id xmlns="">2</Id>
</Test>

为什么?有什么办法可以阻止吗?

1 个答案:

答案 0 :(得分:0)

在您的评论中,您提到您希望将空值用作缺少Email元素的默认值。

这是架构级问题,与序列化程序或代理生成器无关。

此类行为应在架构中定义,而不是留给序列化程序。不幸的是,XML Schema doesn't allow default element values因为它太复杂而无法猜测默认元素的结构是什么。它本身是否需要元素?阵列?选择元素呢?

XML Schema允许默认或固定属性值 allowed,但使用defaultfixed属性。

一种解决方案是创建一个您认为有效的空Email对象的实例,并使用它而不是空值。

static readonly EmptyEmail=new Email();
...
test.Email=test.Email??EmptyEmail;

实际上,这是Null Object pattern的一种情况 - 使用Null Object实例而不是null值。许多.NET Framework类将Null对象存储为类本身上名为Empty的静态只读字段。这样可以使代码更清晰:

test.Email=test.Email??Email.Empty;

另一种选择是初始化类的构造函数中的Email属性。 XSD生成的类是partial的,它允许您在部分文件中定义一个构造函数,在重新生成代理时不会被覆盖,例如:

public partial class Test 
{
    public Test()
    {
        Email=new Email();
    }

}