質問
WSTransfer実装を作成しようとしています(Roman Kissが既にWCF用に作成していることを認識していますが、実際には仕様を満たしていません)
WSTransferは疎結合であるため、サービス連絡先のデータコントラクトを放棄しました。そのため、作成メッセージはそれぞれMessage Create(Message request)のようになります。
これは問題なく機能し、応答を返すまではすべてが素敵です。
私が抱えている問題は、WSTransferレスポンスの作成方法にあります。 createを例にとると、応答は次のようになります
<wxf:ResourceCreated>
<wsa:Address>....</wsa:Address>
<wsa:ReferenceProperties>
<xxx:MyID>....</xxx:MyId>
</wsa:ReferenceProperties>
</wxf:ResourceCreated>
ご覧のとおり、応答メッセージには3つの異なるXML名前空間があります。
今、関与していれば十分簡単です。 (公開していない場合でも)データコントラクトを作成して値を設定し、それを実行することができます
Message response = Message.CreateMessage(request.Version,
"http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse",
resourceCreatedMessage);
ただし、応答内の子要素に異なる名前空間を設定する際に問題が発生します。 WCFのデータ契約ではこれが行われていないようです。使用する
[MessageBodyMember(Namespace="....")]
応答クラス内の個々の要素は変更を加えていないように見え、すべてがコントラクトクラスに指定されたネームスペースの一部になります。
では、WCFメッセージの個々の要素に異なる名前空間をどのように適用しますか。契約を介して、または他のジッガリーポケリーを介して?
解決 2
したがって、jezellの回答をフォローアップします。メッセージを手動で作成するときにXmlSerializationを使用する場合の問題は、ルートの子要素の要素名がマングルされることです。これは、手動でメッセージを作成するときに[XmlSerializerFormat]としてマークされている操作コントラクトにもかかわらず、DataContractSerializerが使用されるためです。
XmlSerializerはXmlSerializerではなくXmlObjectSerializerを必要とするため、Message.CreateMessage()に渡すことはできません。
その答えは、XmlObjectSerializerを基本クラスとして持つXmlSerializerのラッパークラスを書くように思われます(ここに例)があり、それを渡します。メッセージ保持クラスとともに。
残念ながら、XMLに接頭辞を設定するのは賢くありません。そのため、次のようなメッセージが表示されます
<ResourceCreated xmlns="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/">http://localhost:8731/Design_Time_Addresses/AddTests/WSTransfer/</Address>
<ReferenceType xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/"></ReferenceType>
しかし、それはすべて同等です。
他のヒント
XML出力を正確に制御する必要があるこのような場合、DataContractまたはMessageContractシリアル化の代わりにXmlSerializerを使用する必要があります。その方法の詳細は次のとおりです。