1

私のアプリケーションには独自のスクリプト言語があり、それを取り除くことはできません(多くの顧客固有のスクリプトが書かれています)。現在、私の顧客は、そのスクリプト言語内から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)を作成する唯一の方法ですか?
  • 作業を続けることができるサンプルコードを見つけるチャンスはありますか?

よろしくお願いします、パトリック

4

3 に答える 3

1

ビルドインコンパイラを使用して、動的コードをその場で生成することができます。
コードから直接(http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspxなどのコードプロバイダーを使用)、またはクラスを直接構築する( http://msdn.microsoftを参照)。例としてcom/en-us / library / system.codedom.compiler.codedomprovider.aspx

コードの生成は、いくつかの方法で実行できます。

  • コードを手動で生成する(C ++で)
  • wsdl.exeをラップします。exeの配布は許可されていないと思うので、注意が必要かもしれません。顧客はSDKをダウンロードする必要があります。
  • この人が行ったようないくつかのWSDLのような機能を実装します:http ://www.west-wind.com/Weblog/posts/625014.aspx
  • 同じことを行うライブラリを使用してください:http ://www.wcfstorm.com/wcf/home.aspx (商用)
于 2010-08-11T08:46:57.777 に答える
1

スクリプト言語で、外部の.NETアセンブリを呼び出すメカニズムを指定できます。リフレクションを使用して関数を見つけ、呼び出すことができます。プラグインが多くのアプリケーションで機能する方法と同様です。

これにより、顧客は外部Webサービスを呼び出すことができるだけでなく、他の多くの拡張機能にも使用できます。

または、顧客が.NETアセンブリを作成することに依存したくない場合は、ユーザーにSOAPメッセージ名、パラメーター名、タイプと値、サービスURLなどを尋ねることでSOAP要求を自分で生成できます。しかし、そうではないと思います。簡単な道になるだろうし、私は自分でそれをしたことがないことを認めます。

于 2010-08-11T07:59:03.950 に答える
0

スクリプト言語の機能を知らなければ、これに答えるのは困難です。

1つのアイデアは、関連する顧客サービスを呼び出し、顧客固有ではない形式でスクリプト情報に戻るファクトリパターンを持つ別の言語でより強力なサービスを作成することです。

もちろん、これは、ドメイン固有のスクリプト言語から最初に別のプログラムを呼び出すことができることを前提としています。

たぶん、Managed Extensibility Framework(または略してMEF)のようなものもあなたのために働くかもしれません。

于 2010-08-11T08:01:50.000 に答える