c# - 在 ASP.NET MVC 中使用路由映射到 ASMX 服务

标签 c# asp.net .net asp.net-mvc

我想知道是否有任何方法可以将 URL 映射到 ASMX 服务,就像它对页面所做的那样(使用 routes.MapPageRoute() 方法)。

当我试图通过将 MapPageRoute 指向我的服务来简单地做到这一点时,我得到了错误

Type 'MvcApplication1.Services.EchoService' does not inherit from 'System.Web.UI.Page'.

马蒂亚斯。

最佳答案

我在试图自己寻找答案时偶然发现了这个问题,既然我确实找到了一种方法,我想我会回答它。

我需要它的原因是因为我要将一个旧的 ASP.NET 网站转换为 ASP.NET MVC,并且出于兼容性目的,我需要一个在特定 URL 上可用的 Web 服务。但是,该 URL 的路径现在由新站点中的 Controller 处理,因此我不能有一个具有相同名称的物理目录(因为这将阻止 Controller 被具有该路径的其他 URL 调用,而不是 Web 服务).

RouteCollection.MapPageRoute 使用的 PageRouteHandler 确实要求目标路径的处理程序来自 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));
    }
}

此路由处理程序将根据请求和服务的映射虚拟路径为 Web 服务创建适当的处理程序。

您现在可以按如下方式为 Web 服务添加路由:

routes.Add("RouteName", new Route("path/to/your/service", new RouteValueDictionary() { { "controller", null }, { "action", null } }, new ServiceRouteHandler("~/actualservice.asmx")));

注意:您必须在路由值字典中指定 Controller 和操作值(即使它们设置为空),否则 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;
}

之后你可以简单地做:

routes.MapServiceRoute("RouteName", "path/to/your/service", "~/actualservice.asmx");

我希望这对某人有所帮助,尽管这个问题已经很久了。 :)

关于c# - 在 ASP.NET MVC 中使用路由映射到 ASMX 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2764925/

相关文章:

c# - 如何在 Xamarin.Forms 上发送短信

c# - Azure服务总线: ReceiveMessagesAsync returns only a subset

c# - 从 IIS 7/8 中的静态内容中删除服务器 header

c# - 我正在使用集合来填充 asp.net 中的 TreeView 。我将如何从树中删除节点

c# - UnitOfWork 与多个同时连接作斗争

c# - csharp 中的单元测试异步任务

按下键时的 C# 和 Unity3D

c# - 我的玩家角色在加载保存位置时掉下盒子

html - 如何从 ckeditor 中删除 HTML 标签到 textarea

c# - 使用 C# 指针