리플렉션을 사용하여 ASP.NET 웹 서비스 호출
-
09-06-2019 - |
문제
ASMX 웹 서비스인 MyService가 있다고 가정해 보겠습니다.서비스에는 MyMethod라는 메서드가 있습니다.다음과 같이 서버 측에서 MyMethod를 실행할 수 있습니다.
MyService service = new MyService();
service.MyMethod();
런타임까지 알려지지 않은 서비스와 메서드를 사용하여 유사한 작업을 수행해야 합니다.
나는 반성이 그것에 대해 갈 수있는 방법이라고 가정하고 있습니다.불행히도, 나는 그것을 작동시키는 데 어려움을 겪고 있습니다.이 코드를 실행하면:
Type.GetType("MyService", true);
다음 오류가 발생합니다.
'App_Web__ktsp_r0, 버전=0.0.0.0, Culture=neutral, PublicKeyToken=null' 어셈블리에서 'MyService' 유형을 로드할 수 없습니다.
어떤 안내라도 감사하겠습니다.
해결책
이것이 최선의 방법인지 확실하지 않습니다.나에게 가장 확실한 방법은 HTTP 요청을 만들고 실제 HTTP GET 또는 POST를 사용하여 웹 서비스를 호출하는 것입니다.귀하의 방법을 사용하면 웹 서비스로 보내는 데이터를 어떻게 설정했는지 잘 모르겠습니다.VB.Net에 몇 가지 샘플 코드를 추가했습니다.
Dim HTTPRequest As HttpWebRequest
Dim HTTPResponse As HttpWebResponse
Dim ResponseReader As StreamReader
Dim URL AS String
Dim ResponseText As String
URL = "http://www.example.com/MyWebSerivce/MyMethod?arg1=A&arg2=B"
HTTPRequest = HttpWebRequest.Create(URL)
HTTPRequest.Method = "GET"
HTTPResponse = HTTPRequest.GetResponse()
ResponseReader = New StreamReader(HTTPResponse.GetResponseStream())
ResponseText = ResponseReader.ReadToEnd()
다른 팁
// 이것을 시도해 보세요 ->
Type t = System.Web.Compilation.BuildManager.GetType("MyServiceClass", true);
object act = Activator.CreateInstance(t);
object o = t.GetMethod("hello").Invoke(act, null);
Reflection이 왜 작동하지 않는지는 모르겠지만(컴파일러가 [WebService]
주석) 문제를 해결할 수 있는 몇 가지 조언은 다음과 같습니다.
WebService를 간단하고 얕게 유지하세요.Facade 패턴의 구현.
Reflection을 통해 쉽게 호출할 수 있어야 하는 구현 클래스에 서비스 위임 계산을 만듭니다.이런 식으로 WebService 클래스는 시스템의 전면일 뿐입니다. 논리가 WebService가 아니라 실제 비즈니스 계층 개체에 연결되므로 이메일 처리기, XML-RPC 프런트엔드 등을 추가할 수도 있습니다.
WebService 클래스를 아키텍처의 UI 레이어 객체로 생각하세요.
누군가가 확장할 수 있는 빠른 답변은 다음과 같습니다.
WSDL 템플릿 앱(WSDL.exe)을 사용하여 서비스 래퍼를 생성하면 SoapHttpClientProtocol 유형의 클래스가 빌드됩니다.수동으로 수행할 수도 있습니다.
public class MyService : SoapHttpClientProtocol
{
public MyService(string url)
{
this.Url = url;
// plus set credentials, etc.
}
[SoapDocumentMethod("{service url}", RequestNamespace="{namespace}", ResponseNamespace="{namespace}", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public int MyMethod(string arg1)
{
object[] results = this.Invoke("MyMethod", new object[] { arg1 });
return ((int)(results[0]));
}
}
이 코드를 테스트하지는 않았지만 WSDL 도구를 실행하지 않고도 독립 실행형으로 작동할 것이라고 생각합니다.
내가 제공한 코드는 원격 호출을 통해 웹 서비스에 연결되는 호출자 코드입니다(어떤 이유로든 실제로 원격이 되는 것을 원하지 않더라도). Invoke 메서드는 이를 다음과 같이 패키징합니다. 비누 전화.실제로 클래스를 참조할 수 있는 한 HTTP를 통해 웹 서비스 호출을 우회하려는 경우 @Dave Ward의 코드가 정확합니다.아마도 내부 유형이 "MyService"가 아닐 수도 있습니다. 확실히 알기 위해서는 컨트롤의 코드를 검사해야 합니다.
@키비:HTTP 성능 저하를 피해야 합니다.원격 호출이 아니므로 모든 작업에 오버헤드가 추가됩니다. ~해야 한다 불필요하다.
@다렌:나는 그 디자인 철학에 확실히 동의합니다.여기서 문제는 내가 서비스나 기본 비즈니스 로직을 제어할 수 없다는 것입니다.
이것은 서버 컨트롤 웹 서비스 자체가 구현되는 방식과 직교하여 임의의 서비스/메서드에 대해 실행해야 합니다.
귀하의 게시물에서 알 수는 없지만 :
명심해야 할 한 가지는 리플렉션을 사용하는 경우 자동 생성된 웹 서비스 클래스(웹 서비스의 WSDL에서 생성된 클래스)의 인스턴스를 생성해야 한다는 것입니다.서비스의 서버측을 담당하는 클래스를 생성하지 마십시오.
따라서 웹 서비스가 있는 경우
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
...
}
클라이언트에서 해당 어셈블리를 참조하여 다음과 같은 작업을 수행할 수 없습니다.
WebService1 ws = new WebService1 ();
ws.SomeMethod();
@라두:인스턴스를 만들고 정확히 그와 같이 메서드를 호출할 수 있습니다.예를 들어 다음 ASMX가 있는 경우:
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class MyService : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"; } }
ASPX 페이지의 코드 숨김에서 다음과 같이 호출할 수 있습니다.
MyService service = new MyService(); Response.Write(service.HelloWorld());
그게 작동하면 안 된다는 말씀이신가요?
이 질문을 다시 살펴보니 ASMX 코드가 사이트의 동적 컴파일의 일부로 임의의 이름을 가진 DLL에 내장된다는 점인 것 같습니다.유형을 조회하는 코드는 기본적으로 자체 어셈블리(받은 오류에 따라 다른 App_Code DLL)와 핵심 라이브러리만 검색합니다.GetType()에 특정 어셈블리 참조 "TypeName, AssemblyName"을 제공할 수 있지만 자동으로 생성된 어셈블리의 경우에는 재컴파일할 때마다 새 이름이 지정됩니다.
해결책....나는 이전에 이것을 직접 해본 적이 없지만 다음과 같은 것을 사용할 수 있어야 한다고 믿습니다.
System.Web.Compilation.BuildManager.GetType("MyService", true)
BuildManager는 자신이 생성한 DLL을 인식하고 어디를 봐야 할지 알고 있기 때문입니다.
나는 이것이 실제로 웹 서비스와 관련이 없다고 생각하지만 그것이 자신의 코드라면 Facade 패턴에 대한 Daren의 말이 맞습니다.