2010-08-11 6 views
1

내 응용 프로그램에는 제거 할 수없는 고유 한 스크립팅 언어가 있습니다 (많은 고객 별 스크립트 작성). 이제는 고객이 스크립팅 언어에서 SOAP 서비스를 호출 할 수 있는지 묻는 중입니다. 물론 호출해야하는 SOAP 서비스는 모든 고객마다 다를 수 있습니다. 이것은 몇 가지 옵션으로 나를 잎 :자신의 스크립팅 언어에서 SOAP 서비스를 동적으로 호출하십시오.

  • 는 고객 별 SOAP 클라이언트 프록시를 생성하기 위해 WSDL 유틸리티를 사용하여 고객 별 SOAP 클라이언트 프록시를 생성하는 내 응용 프로그램
  • 를 사용하여 WSDL 유틸리티에서 고객 별 논리를 넣어 동적으로 SOAP 호출을 생성하는 일반적인 모듈을 쓰기 응용 프로그램이 일반적인 방법
  • 에 플러그인을 호출 할 수있는 플러그인 시스템을 고객의 특정 DLL의에서 고객 별 논리를 넣어 예상

처음 두 옵션은 n 내 응용 프로그램 또는 고객 특정 DLL의 모든 고객 특정 논리를 원하지 않기 때문에 내 경우에는 o 진짜 대안.

제 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이 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 특성 (예 : GetPrimo)의 웹 서비스 이름을 변경하면이 동일한 오류가 발생합니다.

따라서, 내 질문 :

  • 이는 WSDL을보고이 경로, 즉에서 계속 의미가 있습니까

    는 (모든) SOAP 서비스에 전화를 '일반화'를 시도 논리를 생성하거나 단순히 것 절대로 작동하지 않아?
  • .Net을 사용하여 동적 인 방법으로 SOAP 호출을 생성하는 다른 좋은 방법이 있습니까?
  • 또는 SOAP 호출을 수행하기 위해 XML (Soap Envelope)을 직접 만드는 유일한 방법은 무엇입니까?
  • 계속 작업 할 수있는 몇 가지 예제 코드를 찾을 수 있습니까? 사전에

감사합니다, 패트릭

답변

1

당신은 외부 .NET 어셈블리를 호출하는 스크립트 언어의 메커니즘을 제공 할 수 있습니다. 리플렉션을 사용하여 함수를 찾고 호출 할 수 있습니다.많은 애플리케이션에서 플러그인이 작동하는 방식과 비슷합니다.

만 고객이 외부 웹 서비스를 호출 할 수 없지만, 다른 많은 개선에 사용할 수 있습니다.

.NET 어셈블리를 작성하는 고객에게 의존하고 싶지 않은 경우 사용자에게 SOAP 메시지 이름, 매개 변수 이름, 유형 및 값, 서비스 URL 등을 요청하여 SOAP 요청을 직접 생성 할 수 있습니다. 그것이 쉬운 길이되지 않을 것이라고 생각하고 나는 결코 그것을 스스로 해본 적이 없다는 것을 인정합니다.

+0

나는이 아이디어를 생각,하지만 난 싶지 않아 몇 가지 이유가 있습니다. 저는 컨설턴트와 고객의 특정 일을하는 또 다른 언어를 혼동하고 싶지 않습니다. 컨설턴트가 멋진 일을하지 못하게하고 싶습니다. 그러나 일단 C#을 사용할 수있게되면 불필요한 일이 발생합니다 (악몽이 ​​될 것입니다. 지원). 스크립트 언어에서 웹 서비스로의 호출을 dirct로 제한하려고합니다. – Patrick

+0

Hemant, 나는 생각을 다시하고 Webservice를 호출하는 Microsoft의 모든 문제에 대해 설명했습니다 (클래스의 메서드가 웹 서비스 메서드 인 yuck과 동일한 이름을 사용한다는 사실에 의존합니다). 그것은 여전히 ​​좋은 생각이며 다른 가능성을 열어 줄 수도 있습니다. 이제 컨설턴트가 고객 별 C#을 작성하지 못하게하고 고객이 제공 한 .Net 어셈블리와 WSDL로 WebService 프록시를 생성하는 것만으로 제한합니다. 감사. – Patrick

0

스크립팅 언어의 기능을 알지 못해도 대답하기가 어렵습니다.

하나 개의 아이디어는 관련 고객 서비스를 호출 비 고객 특정 형식으로 스크립트 정보를 반환하는 공장 패턴이 다른 언어보다 강력한 서비스를 만들 수 있습니다. 물론이의

는 도메인 특정 스크립트 언어에서 처음에 다른 프로그램을 호출 할 수 있습니다 가정한다.

아마 Managed Extensibility Framework (or MEF for short) 같은 너무 당신을 위해 일할 수 있습니다.

1
당신은 컴파일러에서 빌드를 사용하여 즉시 동적 코드를 생성 할 수

.
하나의 코드를 생성

직접 코드에서 (http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx 같은 코드 공급자를 사용) 또는 직접 클래스를 구축하여 (예는 http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.aspx 참조)은 여러 가지 방법으로 수행 할 수 있습니다

  • 수동을 생성 code (in C++)
  • wsdl.exe를 래핑합니다. exe를 배포 할 권한이 없다고 생각하기 때문에 까다로울 수 있습니다. 고객이 SDK를 다운로드해야합니다. http://www.west-wind.com/Weblog/posts/625014.aspx
  • 당신을 위해 동일한 작업을 수행하는 라이브러리 사용 :
  • 는 않은이 사람과 같은 몇 가지 WSDL 같은 기능을 구현 http://www.wcfstorm.com/wcf/home.aspx (광고를)
+0

좋은 아이디어. 프록시 클래스를 작성하는 방법은 무엇입니까? C++에서 직접 생성하거나, WSDL 유틸리티를 사용하여 고객에게 생성하거나, 내 응용 프로그램 내에서 WSDL URL을 기반으로 .Net 클래스를 사용하여 생성 할 수 있습니까? – Patrick

+0

업데이트 된 답변보기 – eli

관련 문제