私のアプリケーションには独自のスクリプト言語があり、それを取り除くことはできません(多くの顧客固有のスクリプトが書かれています)。現在、私の顧客は、そのスクリプト言語内からSOAPサービスを呼び出すことが可能かどうかを尋ねています。もちろん、呼び出す必要のあるSOAPサービスは顧客ごとに異なります。これは私にいくつかのオプションを残します:
- WSDLユーティリティを使用して、顧客固有のSOAPクライアントプロキシを生成し、顧客固有のロジックをアプリケーションに配置します
- WSDLユーティリティを使用して、顧客固有のSOAPクライアントプロキシを生成し、顧客固有のロジックを顧客固有のDLLに配置し、アプリケーションが一般的な方法でプラグインを呼び出すことができるプラグインシステムを予測します。
- SOAP呼び出しを動的に生成する汎用モジュールを作成します
私の場合、最初の2つのオプションは、アプリケーションに顧客固有のロジックや顧客固有のDLLが必要ないため、実際の代替手段ではありません。
私にとって、3番目のオプションは、コンサルタントの同僚が顧客固有の開発を行うことなく、スクリプト言語を介してSOAPサービスを呼び出すことができるため、長期的には最適です。スクリプト言語に関数を動的に追加することは問題ではありません。動的なSOAP呼び出しを生成することは問題です。
まず、WSDLユーティリティの出力を確認しました。それから私はそれがもはや機能しなくなるまで物事を取り除き始めました。次のコードはまだ機能しています。
[System::CodeDom::Compiler::GeneratedCodeAttribute(L"wsdl", L"4.0.30319.1"),
System::Diagnostics::DebuggerStepThroughAttribute,
System::ComponentModel::DesignerCategoryAttribute(L"code"),
System::Web::Services::WebServiceBindingAttribute(Name=L"MyOwnScriptingSoapClient", Namespace=L"http://microsoft.com/webservices/")]
public ref class MyWebService : public System::Web::Services::Protocols::SoapHttpClientProtocol
{
public:
MyWebService() {}
public:
[System::Web::Services::Protocols::SoapDocumentMethodAttribute(L"http://microsoft.com/webservices/GetPrimeNumbers", RequestNamespace=L"http://microsoft.com/webservices/",
ResponseNamespace=L"http://microsoft.com/webservices/", Use=System::Web::Services::Description::SoapBindingUse::Literal, ParameterStyle=System::Web::Services::Protocols::SoapParameterStyle::Wrapped)]
System::String^ GetPrimeNumbers(System::Int32 max);
};
inline System::String^ MyWebService::GetPrimeNumbers(System::Int32 max) {
cli::array< System::Object^ >^ results = this->Invoke(L"GetPrimeNumbers", gcnew cli::array< System::Object^ >(1) {max});
return (cli::safe_cast<System::String^ >(results[0]));
}
Urlプロパティを設定することでWebサービスのURLを動的にすることができますが、メソッド名を動的にする方法が見つかりません。
このようなジェネリックメソッドを追加しても、まだ機能しているようです。
...
[System::Web::Services::Protocols::SoapDocumentMethodAttribute(L"http://microsoft.com/webservices/GetPrimeNumbers", RequestNamespace=L"http://microsoft.com/webservices/",
ResponseNamespace=L"http://microsoft.com/webservices/", Use=System::Web::Services::Description::SoapBindingUse::Literal, ParameterStyle=System::Web::Services::Protocols::SoapParameterStyle::Wrapped)]
cli::array< System::Object^ >^ CallWs(cli::array< System::Object^ >^ args);
...
inline cli::array< System::Object^ >^ MyWebService::CallWs(cli::array< System::Object^ >^ args) {
cli::array< System::Object^ >^ results = this->Invoke(L"GetPrimeNumbers", args);
return results;
しかし、GetPrimeNumbersメソッドを削除するとすぐに、呼び出しは機能しなくなり、次のエラーが報告されます。
Unhandled Exception: System.ArgumentException: GetPrimeNumbers Web Service method name is not valid.
at System.Web.Services.Protocols.SoapHttpClientProtocol.BeforeSerialize(WebRequest request, String methodName, Object[] parameters)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at MyWebService.CallWs(Object[] args)
at main(Int32 argc, SByte** argv)
at _mainCRTStartup()
また、SoapDocumentMethodAttribute属性のWebサービス名を(たとえばGetPrimoに)変更すると、これと同じエラーが発生します。
したがって、私の質問:
- このパスを続行することは意味がありますか?つまり、(任意の)SOAPサービスへの呼び出しを「一般化」しようとするWSDL生成ロジックを調べることは意味がありますか、それともこれは単に機能しませんか?
- 動的な方法で(.Netを使用して)SOAP呼び出しを生成する他の良い方法はありますか?
- または、SOAP呼び出しを行うために自分でXML(Soap Envelope)を作成する唯一の方法ですか?
- 作業を続けることができるサンプルコードを見つけるチャンスはありますか?
よろしくお願いします、パトリック