Xsd.exe generated class doesn't serialize mandatory elements when null value

随声附和 提交于 2019-12-12 01:51:33

问题


In the following XSD all elements are mandatory:

<?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>

However, when I serialize an instance of the xsd.exe generated class where EMail == null, the resulting XML is invalid according to the schema, because the EMail element is missing altogether.

<?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>

Why is that? Is there any way to prevent it?


回答1:


In your comments you mention that you want an empty value to be used as a default for a missing Email element.

This is a schema-level problem, not related to the serializer or the proxy generator.

Such behaviour should be defined in the schema, not left to the serializer. Unfortunately, XML Schema doesn't allow default element values because it's far too complex to guess what the default element's structure would be. Does it have required elements itself? Arrays? What about choice elements?

XML Schema does allow Default or fixed attribute values are allowed though, using the default and fixed attributes.

One solution is to create an instance of what you consider a valid empty Email object and use it instead of null values.

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

In fact, this is one case of the Null Object pattern - use a Null Object instance instead of null values. A lot of .NET Framework classes store the Null object as a static readonly field called Empty on the class itself. This makes for a bit cleaner code:

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

Another option is to initialize the Email property in the class's constructor. XSD generated classes are partial which allows you to define a constructor in a partial file that won't be overwritten when you regenerate the proxy, eg:

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

}


来源:https://stackoverflow.com/questions/29841041/xsd-exe-generated-class-doesnt-serialize-mandatory-elements-when-null-value

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