문제

임의의 스크립팅 언어로 작성된 스크립트가 웹 서비스 메서드를 동적으로 노출할 수 있도록 C# ASP.NET 프로젝트에서 클래스를 사용하고 있습니다. 즉, 스크립트는 서명이 있는 모든 이름의 메서드를 노출할 수 있어야 합니다. 어쨌든 유효하기 때문에) 이 SOAP 인터페이스를 통해 외부 세계에 연결됩니다(하드 코드 변경 없이 마음대로 추가 및 제거 가능). 따라서 가능한 동안 C#에서 웹 서비스 클래스를 생성할 수 있어야 합니다. 런타임 시 동적으로 메서드를 추가하고 제거합니다.

이제 지금까지 생각해낼 수 있었던 최고의 계획은 (런타임) 웹 서비스를 나타내는 C# 코드를 생성하고 System.Reflection.Emit를 사용하여 이를 컴파일한 다음 런타임에 어셈블리를 로드하는 것입니다. 이 모든 것은 스크립트가 추가될 때마다 수행됩니다. 또는 서비스와의 메소드를 제거합니다(자주 발생해서는 안 됩니다).

이것보다 더 좋은 아이디어를 가진 사람이 있나요?

도움이 되었습니까?

해결책

다음을 사용하여 WSDL을 수정할 수 있습니다. 비누확장반사경 수업.에서 커크 에반스 블로그:

서비스에 대한 WSDL 정의를 제공하기 위해 유형이 반영될 때 SoapExtensionReflector가 호출됩니다.이 유형을 활용하여 리플렉션 호출을 가로채고 WSDL 출력을 수정할 수 있습니다.

다음 예에서는 2개의 웹 서비스 메서드 중 첫 번째 메서드를 제거합니다.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
   [WebMethod]
   public string HelloWorld()
   {
      return "Hello World";
   }

   [WebMethod]
   public int Multiply(int a, int b)
   {
      return a * b;
   }
}

SoapExtensionReflector에서 상속된 클래스를 만듭니다.

namespace TestWebservice
{
   public class MyReflector : SoapExtensionReflector
   {
      public override void ReflectMethod()
      {
         //no-op
      }

      public override void ReflectDescription()
      {
         ServiceDescription description = ReflectionContext.ServiceDescription;
         if (description.PortTypes[0].Operations.Count == 2)
            description.PortTypes[0].Operations.RemoveAt(0);
         if (description.Messages.Count == 4)
         {
            description.Messages.RemoveAt(0);
            description.Messages.RemoveAt(0);
         }
         foreach (Binding binding in description.Bindings)
         {
            if (binding.Operations.Count == 2)
               binding.Operations.RemoveAt(0);
         }
         if (description.Types.Schemas[0].Items.Count == 4)
         {
            description.Types.Schemas[0].Items.RemoveAt(0);
            description.Types.Schemas[0].Items.RemoveAt(0);
         }
      }
   }
}

web.config의 구성/system.web 섹션에 다음을 추가합니다.

<webServices>
   <soapExtensionReflectorTypes>
      <add type="TestWebservice.MyReflector, TestWebservice" />
   </soapExtensionReflectorTypes>
</webServices>

이는 WSDL 문서에서 메소드를 동적으로 제거하기 위한 시작점을 제공합니다.또한 비활성화된 경우 웹 메서드에서 NotImplementedException을 발생시켜야 합니다.

마지막으로 ?WSDL 매개변수 없이 .asmx 엔드포인트를 호출하여 생성된 웹 서비스 문서를 비활성화해야 합니다.wsdlHelpGenerator 요소의 href 속성을 일부 URL로 설정합니다.DefaultWsdlHelpGenerator.aspx를 자체 문서 처리기의 시작점으로 사용할 수 있습니다.웹 서비스 문서에 대한 질문을 참조하세요. XML 파일, 2002년 8월.

다른 팁

XMLRPC는 상당히 죽었습니까?

비누는 WSDL을 암시합니다. WSDL을 어떻게 동적으로 생성합니까?

WCF를 사용하여 조사해야합니다. WSDL (및 기타 메타 데이터)을 생성하는 프로세스를 제어 할 수있을 것으로 기대하지만, 들어오는 메시지의 처리를 제어 할 수 있어야합니다. 특히, 들어오는 메시지를 검사하여 실행할 스크립트, 전달할 매개 변수 등을 결정할 수 있습니다.

입력 및 출력 유형의 WCF 서비스를 만들 수 있습니다. xs:any 들어오는 요청을 원시로 처리하십시오 Message. 그러면 모든 유형의 데이터를 수락하고 모든 유형의 데이터를 반환 할 수 있습니다. 데이터 계약이나 정적 유형을 사용하지 않고 Message 그리고 a Message 밖으로.

이 접근법의 문제점은 WSDL에서 프록시를 생성하는 것이 실제로 래퍼를 제공하는 것 외에는 소비자가 방법을 호출하는 데 도움이되지 않는다는 것입니다. 이 방법에 허용되는 데이터를 제공하려면 손으로 바르는 데이터 유형 등이 필요하지 않으므로 어려운 계약만큼 직관적이지 않습니다.

비누 인터페이스 여야합니까? 그것은 경로/REST/etc 기반 API에 더 적합한 것처럼 들립니다. ASP.NET MVC에서 무언가를 할 수 있습니다 (사용자 정의 포함 IController.Execute 방법으로 작업을 해결하는 방법)는 아주 쉽게 (사실, 나는 매우 유사한 일을하고 있습니다. 내 코드 중 일부 현재).

예를 들어, 노선이있을 수 있습니다.

http://myserver/myservice/mymethod

이는 (신체 또는 args에서) 페이로드 (매개 변수)를 받아들이고 결과를 응답에 반환합니다. 비 MVC에서는 와일드 카드 매핑 된 일반 핸들러와 비슷한 일을 할 수 있어야합니다.

다음은 제안입니다.

  • WCF를 사용하십시오.
  • 다음 블로그 게시물에서 정보를 사용하여 WCF에서 WSDL을 만듭니다.

    http://www.pluralsight.com/community/blogs/kirillg/archive/2006/06/18/28380.aspx

  • 그런 다음 MEX를 사용 하여이 정보를 게시 할 수 있습니다.

  • 그런 다음 고객이 메타 데이터를로드하고 서비스를 호출 할 수 있도록 서비스가 열려 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top