问题
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