XML模式绑定支持中
{propertyName}Specified记录了该模式的意图:MinOccurs属性绑定支持。添加它是为了支持XSD架构元素,其中:- 该
<element>
元素是参与。 - minOccurs 为零。
- 该 maxOccurs的 属性使然一个实例。
- 数据类型转换为值类型。
在这种情况下,
xsd.exe /classes将自动生成(或您可以手动生成)与架构元素同名的属性,以及一个
{propertyName}Specified布尔型的get/ set属性 ,该 属性 跟踪该元素是否在XML中遇到,并应序列化回XML。
如果遇到元素,
{propertyName}Specified则设置为true,否则设置为
false。因此,反序列化的实例可以确定属性是否在原始XML中未设置(而不是显式设置为默认值)。
逆也用于模式生成。如果您定义具有一对与上述模式匹配的属性的C#类型,然后用于
xsd.exe生成相应的XSD文件,
minOccurrs则会将适当的XSD文件添加到架构中。例如,给定以下类型:
public class ExampleClass{ [XmlElement] public decimal Something { get; set; } [XmlIgnore] public bool SomethingSpecified { get; set; }}将生成以下架构,反之亦然:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="ExampleClass" nillable="true" type="ExampleClass" /> <xs:complexType name="ExampleClass"> <xs:sequence> <xs:element minOccurs="0" maxOccurs="1" name="Something" type="xs:decimal" /> </xs:sequence> </xs:complexType></xs:schema>
请注意,虽然
xsd.exe只记录了
{propertyName}Specified为值类型属性自动生成属性的情况,XmlSerializer但是当手动将其用于引用类型属性时,将遵循该模式。
您可能会问,为什么在这种情况下
xsd.exe不绑定到
Nullable<T>?可能是因为:
- 空变量用于支持
xsi:nil="true"
属性。请参阅Xsi:nil属性绑定支持。 - 在.Net 2.0之前没有引入可空变量,所以也许将其用于此目的为时已晚?
您需要了解这种模式,因为
xsd.exe有时会自动为您生成该模式,但是属性与其
Specified属性之间的交互很奇怪,并且容易产生错误。您可以填充类中的所有属性,然后序列化为XML并丢失
所有内容,
因为您也没有将相应的
Specified属性设置为
true。这里有时会出现这个“陷阱”,例如,也可以参见这个问题或这个问题。
这种模式的另一个“陷阱”是,如果您需要使用不支持该模式的序列化程序来序列化类型,则 可能 要在序列化过程中手动抑制此属性的输出,并且 可能
需要在反序列化过程中手动进行设置。由于每个序列化程序可能都有自己的自定义机制来抑制属性(或者根本没有机制!),随着时间的推移,这样做会变得越来越繁重。
(最后,对于
MyPropertySpecified没有设置器的情况下您的工作成功,我感到有些惊讶。我似乎想起了.Net
2.0的一个版本,在该版本中,缺少
{propertyName}Specified设置器会导致抛出异常。但是在更高版本中,它不再可复制,我没有要测试的2.0。所以这可能是第三个陷阱。Windows窗体控件的“属性”中
ShouldSerialize{PropertyName}()记录了对该方法的支持:使用ShouldSerialize和Reset方法定义默认值。如您所见,文档位于MSDN的Windows窗体部分而不是该XmlSerializer部分,因此实际上是半隐藏功能。我不知道为什么支持此方法和
Specified属性都存在于中
XmlSerializer。
ShouldSerialize是在.Net 1.1中引入的,我 相信 Min.ccurs绑定支持是在.Net
2.0中添加的,所以也许早期的功能不能完全满足
xsd.exe开发团队的需求(或品味)?
因为它是方法而不是属性,所以它缺少模式的“陷阱”
{propertyName}Specified。它在实践中似乎也更流行,并且已被其他序列化器采用,包括:- Json.NET
- protobuf-net(声称支持这两种模式。)
那么,使用哪种模式?
如果自动为您
xsd.exe
生成{propertyName}Specified属性,或者您的类型需要跟踪XML文件中是否出现了特定元素,或者您需要自动生成的XSD来指示某个值是可选的,请使用此模式并当心“陷阱”。否则,请使用该
ShouldSerialize{PropertyName}()模式。它的陷阱更少,并且可能得到更广泛的支持。



