Using reflection to call an ASP.NET web service

Say I have an ASMX web service, MyService. The service has a MyMethod method. I can execute MyMethod on the server side as follows:

MyService service = new MyService(); service.MyMethod(); 

I need to do this, with a service and method unknown before execution.

I guess thinking is a way around this. Unfortunately, it’s hard for me to work. When I execute this code:

 Type.GetType("MyService", true); 

It throws this error:

Failed to load type 'MyService' from assembly 'App_Web__ktsp_r0, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null'.

Any guidance would be appreciated.

+7
reflection c # web-services
source share
8 answers

I am not sure if this will be the best way. The most obvious way for me is to make an HTTP request and call the web service using the actual HTTP GET or POST. Using your method, I'm not quite sure how you configured the data sent to the web service. I have added some code examples in 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() 
+2
source share

Although I don’t know why Reflection doesn’t work for you there (I assume that the compiler can create a new class from your [WebService] annotations), here are some tips that can solve your problem:

Keep your WebService simple, shallow, shorter: implementing a facade template .

Make your delegation a service delegate to an implementation class that can easily be invoked through Reflection. Thus, your WebService class is just the front end for your system - you can even add an email handler, XML-RPC interface, etc., since your logic is not related to WebService, but to a real business-level object.

Think of WebService classes as user interface level objects in your architecture.

+1
source share

Here is a quick answer that can probably expand.

When you use the WSDL templating application (WSDL.exe) to generate service wrappers, it creates a class like SoapHttpClientProtocol. You can also do this manually:

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

I have not tested this code, but I think it should work autonomously without having to run the WSDL tool.

The code I provided is the caller’s code, which connects to the web service through a remote call (even if for some reason you don’t actually want it to be deleted.) The Invoke method takes care of packing it like a Soap call. The @Dave Ward code is correct if you want to bypass the web service call through HTTP - as long as you can actually reference the class. Perhaps the internal type is not "MyService" - you will need to check the control code to know for sure.

+1
source share

// Try This →

  Type t = System.Web.Compilation.BuildManager.GetType("MyServiceClass", true); object act = Activator.CreateInstance(t); object o = t.GetMethod("hello").Invoke(act, null); 
+1
source share

@Kibbee: I need to avoid HTTP performance. This will not be a remote call, so all this additional overhead should not be superfluous.

@Daren: I definitely agree with this design philosophy. The problem here is that I will not control the service or its underlying business logic.

This is for server control , which must be performed against an arbitrary service / method, orthogonal to how the web service itself is implemented.

0
source share

Although I can not say from your message:

Keep in mind that if you use reflection, you need to create an instance of the autogenerated webservice class (the one created from the WSDL of your web service). Do not create a class that is responsible for the server side of the service.

So if you have a web service

  [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] public class WebService1 : System.Web.Services.WebService { ... } 

you cannot reference this assembly in your client and do something like:

 WebService1 ws = new WebService1 (); ws.SomeMethod(); 
0
source share

@Radu: I can instantiate and call the method exactly like that. For example, if I have this 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";
   }
 } 

I can call it from ASPX code as follows:

  MyService service = new MyService ();
 Response.Write (service.HelloWorld ()); 

You say you shouldn't work?

0
source share

I looked at this question again, and I think that you are faced with the fact that the ASMX code will be embedded in a DLL with a random name as part of the dynamic compilation of your site. Your default type search code will only search for its own assembly (another App_Code DLL, the appearance of the error you received) and the main libraries. You can provide a specific reference to the assembly "TypeName, AssemblyName" in GetType (), but this is not possible with automatically generated assemblies that have new names after each recompilation.

Decision. I haven't done this before, but I think you should use something like this:

 System.Web.Compilation.BuildManager.GetType("MyService", true) 

since BuildManager knows about the created DLLs and knows where to look.

I think this is really not related to web services, but if this is your own code, Darren is right about the facade templates.

0
source share

All Articles