Mat*_*zak 5 .net c# asp.net asp.net-mvc
我想知道是否有任何方法可以将URL映射到ASMX服务,就像使用页面(使用routes.MapPageRoute()方法)一样.
当我尝试将MapPageRoute指向我的服务时,我得到了错误
类型'MvcApplication1.Services.EchoService'不从'System.Web.UI.Page'继承.
马提亚.
我偶然发现了这个问题,试图找到答案,因为我确实找到了办法,我想我会回答它.
我需要这个的原因是因为我正在将一个旧的ASP.NET网站转换为ASP.NET MVC,出于兼容性目的,我需要一个特定URL的Web服务.但是,该URL的路径现在由新站点中的Controller处理,因此我不能拥有具有相同名称的物理目录(因为这将阻止对具有除Web服务之外的路径的其他URL调用控制器).
的PageRouteHandler,这是使用RouteCollection.MapPageRoute,确实需要对目标路径的处理程序从派生System.Web.Page,这对于Web服务的情况.因此,有必要创建一个自定义页面处理程序:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
此路由处理程序将根据请求和映射的服务虚拟路径为Web服务创建适当的处理程序.
您现在可以为Web服务添加路由,如下所示:
routes.Add("RouteName", new Route("path/to/your/service", new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/actualservice.asmx")));
Run Code Online (Sandbox Code Playgroud)
注意:您必须在路由值字典中指定控制器和操作值(即使它们已设置为null),否则Html.ActionLink帮助程序将始终对每个链接使用此路由(除非在此路由之前在列表中找到匹配项).由于您可能希望在默认MVC路由之前添加此路由,因此重要的是它不会以这种方式匹配.
当然,您可以创建自己的扩展方法来缓解此任务:
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;
}
Run Code Online (Sandbox Code Playgroud)
之后你可以简单地做:
routes.MapServiceRoute("RouteName", "path/to/your/service", "~/actualservice.asmx");
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助某人,尽管这个问题的年龄.:)