4

私は、Java で実装されているように見える外部ベンダーの Web サービス (Apache Axis だと思います) を使用しており、WCF クライアントでそれを使用しています。いくつかの操作では、列挙型の入力パラメーターが必要です。問題は、特定の場合に渡される列挙型のみが必要なことです。要素は、WSDL で nillable としてマークされていません。ただし、それらは列挙型であるため、指定されていなくても、私の 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は通常、 bool fieldNameSpecifiedパラメーターを追加してオプションのパラメーター (minOccurs=0) を生成し、呼び出し元がフィールドをシリアル化する必要があるかどうかを示す必要があるようです (これについては、こちらこちら、およびここで)。

ただし、この場合、パラメーターは次のように参照されます。

[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のスキーマ リファレンスに準拠していません。このため、svcutil は XmlSerializer にフェールバックしています。

問題は、メソッドのメッセージ コントラクトはまだ生成されていますが、データ コントラクトは生成されていないことです。これは、メッセージから除外できないという点で、デフォルトで nullable でない型に問題をもたらすようです (誰でもこれを確認できますか?)。何らかの理由でXmlSerializerのparameterNameSpecifiedMessageBodyMemberAttributeメソッドが無視されるように見える場合、パラメーターに

この動作を回避できた唯一の方法は/wrapped、svcutil でオプションを使用することです。これにより、メッセージ コントラクトが実際のシリアル化されたパラメーター自体から分離されます。この場合、svcutilparameterNameSpecifiedメソッドを生成し、XmlSerializer はそれらに準拠します。

4

1 に答える 1

3

この問題を調査した結果、私が見つけた唯一の解決策は、svcutil で /wrapped オプションを使用してプロキシを生成することです。上記の質問で参照されているように、これにより抽象化のレイヤーが追加され、メッセージ コントラクトがパラメーターより上のレイヤーに存在できるようになります。この場合、XmlSerializer はfieldNameSpecifiedプロパティを生成し、それらに準拠します。

于 2012-02-03T14:09:15.533 に答える