我有一个关于WCF和XML反序列化的问题。
假设我有一个XSD,它指定了一些属性,如minoccurs ='0'。
<xs:element name=TestData>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs=0 name="stoppageHours>
<xs:simpleType>
<xs:restriction base="xs:int">
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs=0 name="stoppageDate>
<xs:simpleType>
<xs:restriction base="xs:dateTime">
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:sequence>
<xs:complexType>
</xs:element>
如果我没有属性的值,我可以省略XML中的元素标签,即
<TestData>
<StoppageHours>26</StoppageHours>
...omitted stoppageDate...
</TestData>
但是,鉴于我已经从XSD到.NET c#生成了类,当我将XML发布到我的Web服务时,它抱怨反序列化已经失败了,因为它期望元素?
如何强制deserialistion进程忽略缺少的XML元素并将有问题的类memeber设置为NULL值?我已经尝试将类成员设置为系统可空类型,但为了使其工作,我必须将XML元素作为xsi:nillable传递?我真正希望能够做的就是省略XML标签。
感谢。
答案 0 :(得分:0)
允许此功能的属性称为EmitDefaultValue。您在服务端的数据合同可能如下所示:
[DataContract]
public class TestData
{
[DataMember(EmitDefaultValue = false)]
public int StoppageHours { get; set; }
[DataMember(EmitDefaultValue = false)]
public DateTime StoppageDate { get; set; }
}
当EmitDefaultValue等于false时,它告诉WCF中的数据协定序列化程序,如果它们的值等于默认值,则从输入中删除元素。对于值类型,序列化程序将在服务器端将值设置为默认值(如果不存在)。所以在这种情况下,如果你通过
<TestData></TestData>
当WCF收到它时,你的对象将具有服务器端的这些值:
<TestData>
<StoppageHours>0</StoppageHours>
<StoppageDate>1/1/0001 12:00:00 AM</StoppageDate>
</TestData>
编辑:根据您的反馈评论,您可能需要做的另一件事是在DataMember上设置IsRequired属性。当我测试此属性时,默认为false,但您可以尝试在合同定义中明确。更新的合同现在看起来像这样:
[DataContract]
public class TestData
{
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int StoppageHours { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public DateTime StoppageDate { get; set; }
}
当值设置为true且节点丢失时,我会收到序列化异常。当IsRequired设置为false时,我可以发送一个空请求:
<TestData></TestData>
并且没有序列化异常。如果这不起作用,那么您可能需要清除临时的asp.net文件并重新启动该服务。测试时我遇到了这个问题。希望这会有所帮助。