Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net 3.5 Routing to Webservice?

I was looking for a way to route http://www.example.com/WebService.asmx to http://www.example.com/service/ using only the ASP.NET 3.5 Routing framework without needing to configure the IIS server.

Until now I have done what most tutorials told me, added a reference to the routing assembly, configured stuff in the web.config, added this to the Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    RouteCollection routes = RouteTable.Routes;

    routes.Add(
        "WebService",
        new Route("service/{*Action}", new WebServiceRouteHandler())
    );
}

...created this class:

public class WebServiceRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // What now?
    }
}

...and the problem is right there, I don't know what to do. The tutorials and guides I've read use routing for pages, not webservices. Is this even possible?

Ps: The route handler is working, I can visit /service/ and it throws the NotImplementedException I left in the GetHttpHandler method.

like image 811
Diogo Gomes Avatar asked Apr 08 '10 15:04

Diogo Gomes


3 Answers

Just thought I would round off this question with a bit more of a detailed solution based on the answer given by Markives that worked for me.

Firstly here is the route handler class which takes the virtual directory to your WebService as its constructor param.

public class WebServiceRouteHandler : IRouteHandler
{
    private string _VirtualPath;

    public WebServiceRouteHandler(string virtualPath)
    {
        _VirtualPath = virtualPath;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new WebServiceHandlerFactory().GetHandler(HttpContext.Current, 
            "*", 
            _VirtualPath, 
            HttpContext.Current.Server.MapPath(_VirtualPath));
    }
}

and the actual usage of this class within the routey bit of Global.asax

routes.Add("SOAP",
    new Route("soap", new WebServiceRouteHandler("~/Services/SoapQuery.asmx")));
like image 134
Michael Mason Avatar answered Oct 20 '22 20:10

Michael Mason


This is for anyone else who wants to do the above. I found it incredibly difficult to find the information.

In the GetHttpHandler(byVal requestContext as RequestContext) as IHttpHandler Implements IRouteHandler.GetHttpHandler method (my version of the above)

This is for Webforms 3.5 by the way (mine's in VB).

You cant use the usual BuildManager.CreateInstanceFromVirtualPath() method to invoke your web servce that's only for things that implement iHttpHandler which .asmx doesn't. Instead you need to:

Return New WebServiceHandlerFactory().GetHandler(
    HttpContext.Current, "*", "/VirtualPathTo/myWebService.asmx",       
    HttpContext.Current.Server.MapPath("/VirtualPathTo/MyWebService.aspx"))

The MSDN documentation says that the 3rd parameter should be the RawURL, passing HttpContext.Current.Request.RawURL doesn't work, but passing the virtual path to the .asmx file instead works great.

I use this functionality so that my webservice can be called by any Website configured in anyway (even a virtual directory) that points (in IIS) to my application can call the application web service using something like "http://url/virtualdirectory/anythingelse/WebService" and the routing will always route this to my .asmx file.

like image 21
Markive Avatar answered Oct 20 '22 18:10

Markive


You need to return an object that implements IHttpHandler, that takes care of your request.

You can check out this article on how to implement a webservice using that interface: http://mikehadlow.blogspot.com/2007/03/writing-raw-web-service-using.html

But this is probably closer to what you want http://forums.asp.net/p/1013552/1357951.aspx (There is a link, but it requires registration, so I didnt test)

like image 1
Cine Avatar answered Oct 20 '22 18:10

Cine