locked
asmx soap extension and response RRS feed

  • Question

  • User-541158125 posted

    I have a particular web method defined in my asmx web service and our application uses those web services. I want to build a new layer above those web service in such a way that whenever a call goes to that web method, a new definiton of the web method (which is a similar method with the same input and output parameters) should get invoked. I was successful in doing it using a httpmodule, where I redirect my request to the new web method. But is it possible to do using a soap extension. can I change the web method definition in soap extension after soap deserialization. I can call the new web method explicitly after soap deserialization, but I need to build the soap response object rather than the asmx handler taking care of it. Is there a way to generate soap response output automatically for the new web method.

    Thanx

    Saturday, March 1, 2014 6:02 AM

Answers

  • User753101303 posted

    Ok rather than to intercept calls to an actual service to direct those calls somewhere else I would try something such as the code below. Basically the service exposes just an interface whose implementation is provided by an underlying class. If I change the string I can use either the "Hello1" or "Hello2" implementation (this string could be taken from the config file).

      public class WebService1 : System.Web.Services.WebService,IHello
        {
            public IHello Impl = (IHello)Activator.CreateInstance(System.Reflection.Assembly.GetExecutingAssembly().FullName,"dpi_lab.Hello1").Unwrap();
            [WebMethod]
            public string HelloWorld()
            {
                return Impl.HelloWorld();
            }
        }
        public interface IHello
        {
            string HelloWorld();
        }
        public class Hello1 : IHello
        {
            public string HelloWorld()
            {
                return "v1";
            }
        }
        public class Hello2 : IHello
        {
            public string HelloWorld()
            {
                return "v2";
            }
        }

     

     

     

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, March 4, 2014 7:46 AM

All replies

  • User753101303 posted

    Hi,

    I would suggest to first explain what you are trying to do (not how you think it could or should be done in technical terms but an overview of your final objective). For now it looks like you have  a method for which you want perhaps to provide a different implementation depending on who is calling the service or whatever ???

    Saturday, March 1, 2014 10:44 AM
  • User-541158125 posted

    Hi,

       Thanks for the reply. I am trying to implement a different definition for  a particular web method in the web service, which improves the performance of the web method call. I cannot change the asmx service url neither can I change the original web method definition. All I wanted to do is whenever user call that web method, I should execute the new web method instead of the old web method. I was able to do it using httpmodule by parsing the request input stream to get the name of the web method and if it matches, I am just redirecting to a new asmx service which has my new web method definition. But httmodule adds overhead (delay) to other web method calls as I am parsing the input stream. But this can be avoided using a soap extension, as I can do it after the deserializing event which is pretty much not adding any delay to the existing web methods. The main objective of this implementations is building something above the existing web service for particular web methods, but should not affect the performance of other web method calls in the same asmx service. Please let me know, if you need any clarifictions.

    Sunday, March 2, 2014 4:59 AM
  • User753101303 posted

    What do you call a "definition" (not sure if you mean the method signature or its implementation) ? If the new method have the same signature I don't see why you couldn't just change the current implementation rather than "hijacking" the call and going throup hops to finally call the same code. You can still keep the old "definition" and create some kind of overload that would allow to call this old one if some client code really needs to. If the signature is not the same client code needs to be recompiled anyway so they should pick the new signature by just refreshing the client proxy class.

    Or you try to change a web method call for a service for which you don't have the source code ?

    Sunday, March 2, 2014 5:33 AM
  • User-541158125 posted

    Hi,

         I am sorry..I meant "implementation" by the word "definition". I know that it is a kind of weird thing to not actually change the implementation of the web method directly rather than re routing it. The whole idea is to switch between implementations of the old and new web methods with just a configuration change rather than recompiling the code. That is  the reason to make it work using a httpmodule or soap extension.

    Sunday, March 2, 2014 11:39 AM
  • User753101303 posted

    I would say it might simpler to just have then a dummy service implementation that would just relay the calls to the actual implementation using a class configured in the web.config file rather than to create a module to intercept calls.

    I'm would have to check that but for WCF services I believe you even get that out of the box (if I remember the service is declared as an interface and you can tell which class implementing this interface should be used).

    This is a plain old ASMX service and you must stay might that or is this WCF based ? It shouldn't be to hard to create a proof of concept.

    Sunday, March 2, 2014 12:30 PM
  • User-541158125 posted

    Hi,

      This is a plain old ASMX service and not WCF based service.

    Sunday, March 2, 2014 11:48 PM
  • User753101303 posted

    Ok rather than to intercept calls to an actual service to direct those calls somewhere else I would try something such as the code below. Basically the service exposes just an interface whose implementation is provided by an underlying class. If I change the string I can use either the "Hello1" or "Hello2" implementation (this string could be taken from the config file).

      public class WebService1 : System.Web.Services.WebService,IHello
        {
            public IHello Impl = (IHello)Activator.CreateInstance(System.Reflection.Assembly.GetExecutingAssembly().FullName,"dpi_lab.Hello1").Unwrap();
            [WebMethod]
            public string HelloWorld()
            {
                return Impl.HelloWorld();
            }
        }
        public interface IHello
        {
            string HelloWorld();
        }
        public class Hello1 : IHello
        {
            public string HelloWorld()
            {
                return "v1";
            }
        }
        public class Hello2 : IHello
        {
            public string HelloWorld()
            {
                return "v2";
            }
        }

     

     

     

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, March 4, 2014 7:46 AM
  • User-541158125 posted

    Hi,

      Thanks. Just wanted to explain you more about the problem we are trying to resolve. We are actually implementing a custom cache layer above our old .asmx web service layer. We were trying a different approach before and so I had to explain you a different problem. But now things seem to be a bit clear. sorry that I should have explained it earlier. The responses from few of the web methods need to be cached and those cached response need to be returned for subsequent calls fo the same web method. We are not allowed to modify the underlying web services code nor the urls. So we were using soap extension because its a config change. This is the approach we are using now. When the webmethod is called for the first time, we are caching the soap message in soapmessagestage.afterserialize method. When a call  comes for the second time, we are able to get the serialised soap message from the cache in the soapmessagestage.afterdeserialize event. But we are facing difficulty in putting the serialized soapmessage in the httpresponse object and ending the response, so that the call does not go forward to execute the method.  we tried copying the soapmessage.stream to httpresponse output stream and do a response.end. But the client was unable to read the response. Is there a way where we can create a response object from soapmessage. Thanx

    Friday, March 7, 2014 1:41 AM