この投稿が長すぎる場合は、事前にお詫び申し上げます。しかし、1) これは私の初めての投稿であり、2) 私は実際に川を渡り、森の中を通り抜けてこれを理解しようとしました.
Visual Studio 2012 のサービス参照の追加機能は、(明らかに) 無効な SOAP メッセージを生成するプロキシを生成します。シリアライゼーションまたはプロキシタイプの装飾方法に関係していると思われますが、理解できないようです。助けていただければ幸いです。
詳細 1. 私の環境は Visual Studio 2012 で、https://sandbox-api.bancbox.com/v1/BBXPort?wsdlへのサービス参照を含む .NET 4.5 クラス ライブラリを作成しました。getClient() 関数を呼び出そうとしています。ここで定義されています。( http://www.bancbox.com/api/view/45 )
コードは次のようになります。
public void GetClient()
{
// create an instance of the service reference proxy class
var bbx=newBBXClient();
bbx.ChannelFactory.Endpoint.Behaviors.Remove<System.ServiceModel.Description.ClientCredentials>();
bbx.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials());
bbx.ClientCredentials.UserName.UserName="MY_USERNAME";
bbx.ClientCredentials.UserName.Password="MY_PASSWORD";
var customerId=newid {
subscriberReferenceId="44XX33YY"
};
var request=newgetClientRequest {
subscriberId=MY_SUBSCRIBER_ID,
clientId=customerId
};
var response=bbx.getClient(request);
}
詳細 2. SoapUI を介して、Web サービスへの多くの呼び出しを成功させました。成功した SoapUI 生成の SOAP メッセージは次のようになります。
<soapenv:Envelope xmlns:sch="schema.bancbox.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-11">
<wsse:Username>MY_USERNAME</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">tRLo6AlRKl+/rULiKq6A6g==</wsse:Nonce>
<wsu:Created>2013-02-22T18:32:02.204Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<sch:getClient>
<getClientRequest>
<subscriberId>MY_SUBSCRIBER_ID</subscriberId>
<clientId>
<!--Optional:-->
<subscriberReferenceId>44XX33YY</subscriberReferenceId>
</clientId>
</getClientRequest>
</sch:getClient>
</soapenv:Body>
</soapenv:Envelope>
詳細 3. Fiddler によると、失敗した SOAP メッセージは次のようになります。
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPozcAgEH0QhJHloqMBWUf3mAAAAAA5wy3enJkDUGU8IaMUCFyEjzfL+1Uez1HhAvEeFpJ+30ACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-6e1c9f81-0651-41f7-b659-26b191bf7e13-1" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<o:Username>MY_USERNAME</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</o:Password>
<o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">hGggJkxurSkHQ3MKoeBK6AmEHNs=</o:Nonce>
<u:Created>2013-02-23T11:24:47.663Z</u:Created>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getClient xmlns="schema.bancbox.com">
<getClientRequest xmlns="">
<subscriberId>MY_SUBSCRIBER_ID</subscriberId>
<clientId>
<subscriberReferenceId>XX55YY22</subscriberReferenceId>
</clientId>
</getClientRequest>
</getClient>
</s:Body>
</s:Envelope>
GetClient() メソッドを実行すると、上記の SOAP メッセージが生成されます。GetClient は次の例外をスローします。
System.ServiceModel.FaultException
Unmarshalling Error: cvc-elt.4.2: Cannot resolve 'getClientRequest' to a type definition for element 'getClientRequest'.
SoapUI を使用して同じ失敗メッセージを再生すると、次の応答が返されます。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: cvc-elt.4.2: Cannot resolve 'getClientRequest' to a type definition for element 'getClientRequest'. </faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
詳細 4.私の調査によると、これは相手側のサーバーが Apache CXS であることを示しています。私のSOAPリクエストで窒息しています。そこで、SOAP メッセージをいじって、SoapUI 経由で送信し始めました。
成功メッセージと私の失敗メッセージの最初のギラギラした距離はこれらの行です
成功
<sch:getClient>
<getClientRequest>
不合格
<getClient xmlns="schema.bancbox.com">
<getClientRequest xmlns="">
そのため、最初に行ったのは、成功したものと同じ getClientRequest タグを作成することでした。
<getClient xmlns="schema.bancbox.com">
<getClientRequest>
これにより、次の応答が生成されました。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Found element {schema.bancbox.com}getClientRequest but could not find matching RPC/Literal part</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
次に、getClient タグにスキーマを割り当てる方法を変更しました。
前
<getClient xmlns="schema.bancbox.com">
後
<s:Envelope xmlns:bb="schema.bancbox.com" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
. . .
<bb:getClient>
<getClientRequest>
. . .
</bb:getClient>
結果の SOAP メッセージは次のようになり、成功です。
<s:Envelope xmlns:bb="schema.bancbox.com" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPozcAgEH0QhJHloqMBWUf3mAAAAAA5wy3enJkDUGU8IaMUCFyEjzfL+1Uez1HhAvEeFpJ+30ACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-6e1c9f81-0651-41f7-b659-26b191bf7e13-1" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<o:Username>MY_USERNAME</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MY_PASSWORD</o:Password>
<o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">hGggJkxurSkHQ3MKoeBK6AmEHNs=</o:Nonce>
<u:Created>2013-02-23T11:24:47.663Z</u:Created>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<bb:getClient>
<getClientRequest>
<subscriberId>MY_SUBSCRIBER_ID</subscriberId>
<clientId>
<subscriberReferenceId>XX55YY22</subscriberReferenceId>
</clientId>
</getClientRequest>
</bb:getClient>
</s:Body>
</s:Envelope>
したがって、百万ドルの質問は、「なぜ」と「どのように」です。
*.NET プロキシ クラスが SOAP メッセージをこのようにシリアライズするのはなぜですか?
*どうすれば修正できますか? プロキシを上記の SOAP メッセージにシリアル化するにはどうすればよいですか? Envelop でメッセージ名前空間の省略形を定義し、メッセージ タグで省略形を使用するようシリアライザに強制するにはどうすればよいですか?
参考までに、ここまでたどり着くまでに、WCF WSE に関する多くの問題を乗り越える必要がありましたが、Rich Stahls ブログで非常に寛大に提供されているソリューションを実装することになりました。リンクを投稿しますが、明らかに十分な担当者がいません。