【问题标题】:svcutil NOT generating specified fields for minOccurs=0svcutil 未为 minOccurs=0 生成指定字段
【发布时间】:2014-04-01 09:16:21
【问题描述】:

我正在使用 svcutil 从 Web 服务生成客户端代理。 WSDL 包含属性 minOccurs 设置为 0 的元素

<xsd:element minOccurs="0" name="dateMaxValue" type="xsd:dateTime"></xsd:element>

但是生成的 DataContract 完全忽略了这个属性,只是创建了一个没有任何 dateMaxValueSpecified 属性的普通 dateMaxValue 属性

private System.DateTime dateMaxValueField;

当我使用选项 /serializer:XmlSerializer 生成代理时,我得到了 xxxSpecified 属性。

private System.DateTime dateMaxValueField;

private bool dateMaxValueFieldSpecified;

编辑

对于可选字段,我希望该字段在没有值时不被发送或不被读取(等效于 XmlSerializer 中的指定=false) 当前传入和传出数据设置为默认值。 如何使用 DataContractSerializer 获得类似的行为? 或者如果它已经存在,我该如何使用它?

【问题讨论】:

  • XmlSerializer 和 DataContractSerializer 遵循不同的序列化规则... DCS 是否甚至遵守 ShouldSerialize* 约定?但最终:如果它不在此列表中,您可能无法使其自动执行:msdn.microsoft.com/en-us/library/aa347733(v=vs.110).aspx - 您也许可以在 partial class 中手动执行。
  • 目前我有 140k 行生成的代码,我可能需要 momre。我没有编辑该文件的每个类来添加所需的行为:s
  • 一个明智的选择 ;p 不过,如果您足够关心,您也许可以将其自动化 - 反射会迭代一些 partial class 文件(或多个文件)的类型和属性,然后您将其放入. 不优雅,但编写脚本只需要几分钟
  • 感谢您的帮助,但似乎我要查找的不是 xxxSpecified 字段。我希望能够检测到 xml 中不存在字段或告诉序列化程序不要序列化某些数据(而不是使用默认值序列化)的方法。我仍然不知道如何使用 DCS 来做到这一点。对我来说,这似乎是一种非常基本的行为。
  • 您是否可以控制 web 服务 wsdl?

标签: c# wcf svcutil.exe


【解决方案1】:

您观察到的行为是正常的:*Specified 字段仅在使用 XmlSerializer 时生成。

DataContractSerializer 从不生成那些 Specified 字段。反而。它会将DataMember 属性的IsRequired 属性设置为false(这是该属性的默认值,因此您甚至不会在属性中看到它)。


外发消息

您想省略传出消息中没有值的字段。 问题是DateTime是一个值类型,也就是说即使没有设置,它也有一个默认值“0001-01-01T00:00:00”。

如果不想在外发消息中输出,可以:

  • EmitDefaultValue = false 属性添加到DataMember 属性。这将阻止元素被写入生成的 xml。
  • 或者,将类型更改为 DateTime? => 这将在您的 xml 文档中输出类似于 &lt;dateMaxValueField i:nil="true"/&gt; 的内容。

不修改代理是没有办法的。

收到的消息

同样的逻辑适用:接收完全省略元素的消息不会有问题(只要代理类中的相应属性具有IsRequired = false)。请注意,由于DateTime 是一种值类型,您将始终使用其默认值(“0001-01-01”)填充它。如果您希望接收null 实例,则需要修改您的代理并使用DateTime? 类型。

但是,如果您希望能够解析包含以下内容的消息:

<dateMaxValueField></dateMaxValueField>

那我恐怕没有办法用 DataContractSerializer 做到这一点。


注意:XmlSerializer 在这些情况下允许更大的灵活性(当需要对 XML 进行精确控制时,例如出于兼容性原因)。

【讨论】:

  • 感谢您的回答,但似乎我没有正确的问题:) 请参阅编辑
  • 我不确定您是否可以使用 DataContractSerializer 做您想做的事情,尤其是如果您对原始 wsdl 没有任何控制权。
  • 好的,我会将您的答案标记为已接受,因为我想没有其他办法了。我真正需要的是为我的字段设置 EmitDefaultValue = false 。但是我还没有找到自动输出它的方法,我无法手动修改所有内容。我将回滚到旧的 XmlSerializer。
猜你喜欢
  • 2012-08-24
  • 2011-09-14
  • 1970-01-01
  • 2013-11-27
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 2015-04-20
相关资源
最近更新 更多