Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I stumbled upon this question trying to find the answer myself, and since I did figure out a way to do it, I figured I'd answer it.</p> <p>The reason I needed this is because I'm converting an old ASP.NET website to ASP.NET MVC, and for compatibility purposes I need a web service available at a specific URL. However, the path of that URL is now handled by a Controller in the new site, so I cannot have a physical directory with the same name (since that will prevent the controller from being invoked for other URLs with that path other than the web service).</p> <p>The <code>PageRouteHandler</code>, which is used by <code>RouteCollection.MapPageRoute</code>, indeed requires that the handler for the target path derives from <code>System.Web.Page</code>, which isn't the case for web services. So instead, it is necessary to create a custom page handler:</p> <pre><code>using System; using System.Web; using System.Web.Routing; using System.Web.Services.Protocols; public class ServiceRouteHandler : IRouteHandler { private readonly string _virtualPath; private readonly WebServiceHandlerFactory _handlerFactory = new WebServiceHandlerFactory(); public ServiceRouteHandler(string virtualPath) { if( virtualPath == null ) throw new ArgumentNullException("virtualPath"); if( !virtualPath.StartsWith("~/") ) throw new ArgumentException("Virtual path must start with ~/", "virtualPath"); _virtualPath = virtualPath; } public IHttpHandler GetHttpHandler(RequestContext requestContext) { // Note: can't pass requestContext.HttpContext as the first parameter because that's // type HttpContextBase, while GetHandler wants HttpContext. return _handlerFactory.GetHandler(HttpContext.Current, requestContext.HttpContext.Request.HttpMethod, _virtualPath, requestContext.HttpContext.Server.MapPath(_virtualPath)); } } </code></pre> <p>This route handler will create an appropriate handler for the web service based on the request and mapped virtual path of the service.</p> <p>You can add a route for a web service now as follows:</p> <pre><code>routes.Add("RouteName", new Route("path/to/your/service", new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/actualservice.asmx"))); </code></pre> <p>Note: you must specify the controller and action values in the route value dictionary (even though they're set to null), otherwise the <code>Html.ActionLink</code> helper will always use this route for every single link (unless a match was found in the list before this route). Since you probably want to add this route before the default MVC route, it's important that it doesn't get matched that way.</p> <p>Of course, you can create your own extension method to alleviate this task:</p> <pre><code>public static Route MapServiceRoute(this RouteCollection routes, string routeName, string url, string virtualPath) { if( routes == null ) throw new ArgumentNullException("routes"); Route route = new Route(url, new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler(virtualPath)); routes.Add(routeName, route); return route; } </code></pre> <p>After which you can simply do:</p> <pre><code>routes.MapServiceRoute("RouteName", "path/to/your/service", "~/actualservice.asmx"); </code></pre> <p>I hope this helps someone, despite the age of this question. :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload