动态调用从自己的脚本语言SOAP服务 [英] Dynamically call SOAP service from own scripting language

查看:381
本文介绍了动态调用从自己的脚本语言SOAP服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序都有自己的脚本语言,而我无法摆脱的(大量的客户特定的脚本编写的)。现在,我的客户都在问,如果有可能从内部的脚本语言调用一个SOAP服务。当然,这需要调用的SOAP服务会为每一位客户的不同。这使我有几种选择:

My application has its own scripting language of which I cannot get rid of (lots of customer-specific scripts written). Now my customers are asking if it would be possible to call a SOAP service from within that scripting language. Of course, the SOAP service that needs to be called will be different for every customer. This leaves me with several options:

  • 使用WSDL实用程序生成客户特定的SOAP客户端代理,并把客户特定的逻辑在我的应用程序
  • 使用WSDL实用程序生成客户特定的SOAP客户端代理,把客户的具体DLL的客户特定逻辑和预见的插件系统中的应用程序可以调用插件在一个通用的方法
  • 在编写一个通用模块,动态生成SOAP调用

第2个选项是在我的情况下,没有真正的选择,因为我不希望在应用程序的任何客户特定的逻辑,或客户指定的DLL的。

The first 2 options are no real alternative in my case since I don't want any customer-specific logic in the application, or customer-specific DLL's.

对于我来说,第三个选择是,从长远来看,因为它最让我的顾问同事打电话给我,通过脚本语言的SOAP服务,而不做任何客户特定的发展。动态地添加功能,我的脚本语言是没有问题的,生成动态SOAP调用。

For me, the 3rd option is, in the long term, the best since it allows my consultant colleagues to call the SOAP service via my scripting language without doing any customer-specific developments. Dynamically adding functions to my scripting language is not a problem, generating the dynamic SOAP call is.

我一开始就着眼于WSDL实用程序的输出。然后,我开始删除的东西,直到它不再起作用。下面的一段code是一个仍在工作:

I started by looking at the output of the WSDL utility. Then I started to remove things until it didn't work anymore. The following piece of code is the one still working:

[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]));
}

Web服务的URL可以是动态地设置Url属性,但我不能找到一种方法,使该方法的名称动态。

The URL of the web service can be dynamically by setting the Url property, but I can't find a way to make the method name dynamic.

添加这样一个通用的方法似乎仍工作:

Adding a generic method like this still seems to work:

...
[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方法,调用不再工作了,并报告了以下错误:

But as soon as I remove the GetPrimeNumbers method, the call doesn't work anymore and reports the following error:

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),给这个同样的错误。

Also, changing the web service name in the SoapDocumentMethodAttribute attribute (e.g. to GetPrimo), gives this same error.

所以,我的问题:

  • 是否有意义,继续这条道路,即在看WSDL上产生的逻辑试图'推广'调用一个(有)SOAP服务还是将根本不会工作?
  • 是否有产生的SOAP调用以动态方式(使用.NET)?任何其他的好办法
  • 或者是创建XML(SOAP信封)自己做的SOAP调用?
  • 的唯一方法
  • 在发现了一些例如code的任何机会,我可以继续工作吗?

在此先感谢, 帕特里克

Thanks in advance, Patrick

推荐答案

您可以给一个机制,你的脚本语言调用外部.NET程序集。您可以使用反射来找到函数和调用它们。在许多应用中类似的方式插件工作。

You can give a mechanism in your scripting language to call an external .NET assembly. You can use reflection to find the function and call them. Similar to way the plugins work in many applications.

此,不仅允许客户调用外部Web服务,但也可以用于许多其它的改进。

This will not only allow the customers to call an external web service, but can be used for many other enhancements.

或者,如果你不希望依赖于你的客户编写.NET程序集,您可以生成SOAP请求自己通过询问用户的SOAP消息的名称,参数的名称,它们的类型和价值,服务URL等,但我认为它不会是一件容易的道路,我承认,我从来没有这样做我自己。

Or if you don't want to rely on your customer writing .NET assemblies, you can generate the SOAP requests yourself by asking the user SOAP message name, parameter names, their type and values, service URL etc. But I think it is not going to be an easy path and I admit that I never have done it myself.

这篇关于动态调用从自己的脚本语言SOAP服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆