WCF反序列化

时间:2012-08-06 14:40:27

标签: wcf

我有一个关于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标签。

感谢。

1 个答案:

答案 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文件并重新启动该服务。测试时我遇到了这个问题。希望这会有所帮助。