【问题标题】:Optional enumeration with WCF clientWCF 客户端的可选枚举
【发布时间】:2012-02-24 07:02:32
【问题描述】:

我正在使用似乎是用 Java 实现的外部供应商的 Web 服务(我相信是 Apache Axis),并且我正在使用 WCF 客户端使用它。一些操作需要枚举类型的输入参数。问题是他们只希望在某些情况下通过枚举。这些元素在 WSDL 中未标记为可空。但是,由于它们是枚举,因此即使未指定,我的 WCF 客户端也将始终传递默认值。这种行为导致他们的服务出现内部错误。

关于如何解决这个问题的任何想法?最好是不需要手动修改代理的解决方案,因为如果将来另一个开发人员要独立生成它,这可能会导致混乱。

特定元素在 WSDL 中指定如下

<xs:complexType name="complexTypeName">
<xs:sequence>
    <!-- More Stuff Here-->
    <xs:element minOccurs="0" name="parameterName" type="tns:parameterName" />
    <!-- More Stuff Here-->
</xs:sequence>
</xs:complexType>

<!-- . . . -->

<xs:simpleType name="parameterName">
  <xs:restriction base="xs:string">
    <xs:enumeration value="ONLY_AVAILABLE_VALUE" />
  </xs:restriction>
</xs:simpleType>

Svcutil 将其翻译为

[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://vendorwebservicenamespace.com/")]
public enum parameterName
{   
    /// <remarks/>
    ONLY_AVAILABLE_VALUE,
}

编辑:经过一番研究,看起来 svcutil 应该通常会生成可选参数 (minOccurs=0) 并带有额外的 bool fieldNameSpecified 参数,允许调用者指示是否应序列化该字段(这已记录在 hereherehere)。

但是,在这种情况下,参数引用如下:

[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://vendorservicenamespace.com/", Order=23)]
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Namespace.parameterName parameterName;

当我尝试手动添加适当的 fieldNameSpecified 方法时,它似乎对序列化没有任何影响(即参数仍然存在于 soap 消息中)。

在这一点上,我想知道

  1. 为什么 svcutil 不包含 fieldNameSpecified 参数?
  2. 为什么手动添加参数似乎不起作用?
  3. 还有其他解决方法可以解决这个问题吗?

编辑:经过更多研究,我确定部分问题在于 WSDL 的编写方式。供应商的 WSDL 不符合 DataContractSerializer 的 Schema Reference。因此,svcutil 将故障回复到 XmlSerializer。

问题在于它仍在为方法生成消息契约,而不是数据契约。这似乎会导致默认情况下不可为空的任何类型出现问题,因为它们无法从消息中排除(任何人都可以验证这一点吗?)。无论出于何种原因,当使用 MessageBodyMemberAttribute 标记参数时,XmlSerializer 的 parameterNameSpecified 方法似乎被忽略(不知道为什么?)

我能够解决此问题的唯一方法是使用带有 svcutil 的 /wrapped 选项。这导致消息合约与实际的序列化参数本身分离。在这种情况下,svcutil 确实 生成 parameterNameSpecified 方法,并且 XmlSerializer 符合它们。

【问题讨论】:

  • 属性是什么样的。是parameterName 还是Nullable&lt;parameterName&gt; 类型?
  • 它作为参数名称生成。 WSDL 没有明确指定参数是“可空的”(nillable = true),所以“可选”是一个更好的词。
  • 如果您找到了解决方案,请将其添加为答案,并接受答案。
  • 我这样做了,因为我找到了解决这个特定问题的方法。我仍然认为根本问题的问题仍未得到解答(即,如何在使用带有 XmlSerializer 的消息协定时正确处理不可为空类型的可选参数),但这不一定是问题的初衷。我可能应该为此发布一个新问题。
  • 任何带有完整源代码示例的最终解决方案?

标签: wcf web-services xml-serialization optional-parameters messagecontract


【解决方案1】:

在研究了这个问题之后,我能找到的唯一解决方案是使用 svcutil 上的 /wrapped 选项生成代理。正如上面问题中提到的,这增加了一个额外的抽象层,并允许消息合约存在于参数之上的一层。在这种情况下,XmlSerializer 会生成 fieldNameSpecified 属性并符合它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多