0

我有一个关于 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 服务时,它抱怨反序列化失败,因为它期望元素?

如何强制反序列化过程忽略丢失的 XML 元素并将有问题的类成员设置为 NULL 值?我尝试将类成员设置为系统可为空的类型,但要使其正常工作,我必须将 XML 元素作为 xsi:nillable 传递?我真正想做的只是省略 XML 标记。

谢谢。

4

1 回答 1

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 文件并重新启动服务。我在测试时遇到了这个问题。希望这可以帮助。

于 2012-08-06T19:07:57.343 回答