【问题标题】:MVC2 Routing with WCF ServiceRoute: Html.ActionLink rendering incorrect links!使用 WCF ServiceRoute 进行 MVC2 路由:Html.ActionLink 呈现不正确的链接!
【发布时间】:2011-04-04 00:12:12
【问题描述】:

我有一个与 MVC2 网站并排存在的 WCF 服务。我希望我的服务 URL 看起来像这样:

http://localhost/projdir/Service

MVC 站点还处于起步阶段,因此它仍然拥有所有样板控制器等。

以下代码在 global.asax 中乍一看是有效的:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new ServiceRoute("Service", new ServiceHostFactory(), 
               typeof(MyService)));

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", 
              id = UrlParameter.Optional } // Parameter defaults
    );
}

该服务出现在我所描述的位置,并且按照宣传的方式工作。太好了。

但是,我刚刚注意到以这种方式订购我的代码会改变我所有的ActionLink。例如,MVC 站点上的“关于”选项卡现在如下所示:

http://localhost/projdir/Service?action=About&controller=Home

这显然是不正确的(应该是 http://localhost/projdir/Home/About/ )。

如果我将 ServiceRoute 添加到默认 MapRoute() 调用下方,则会收到缺少控制器错误。 (实际上我得到一个“StructureMapControllerFactory 没有返回控制器的实例”错误,因为我连接到 StructureMap,呃,它一开始就不是控制器。)

有趣的是,它似乎只影响了Html.ActionLink() 的输出。我可以手动输入http://localhost/projdir/Home/About/ 并进入正确的页面。

我犯了什么可怕的新手错误?

【问题讨论】:

标签: wcf asp.net-mvc-2 asp.net-mvc-3 routing


【解决方案1】:

我解决了:

     routes.MapRoute(
             "Default", // Route name
             "{controller}/{action}/{id}", // URL with parameters
             new { controller = "Home", action = "Index", id = UrlParameter.Optional },
             new { controller = "^(?!api).*" }
        );
        routes.Add(new ServiceRoute("api", new DataServiceHostFactory(), typeof(dwService)));

我希望这对你有好处

【讨论】:

  • 太棒了——我完全忘记了那些过滤器!谢谢!
【解决方案2】:

另一种解决方案是继承ServiceRoute并覆盖GetVirtualPath方法以返回null,如here所述

public class AppServiceRoute : ServiceRoute
{
    public AppServiceRoute(string routePrefix, ServiceHostFactoryBase serviceHostFactory, Type serviceType)
        : base(routePrefix, serviceHostFactory, serviceType)
    {
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

这样,反向路由映射永远不会为任何操作选择此路由。像魅力一样工作

【讨论】:

    【解决方案3】:

    尝试在 MVC 路由之后移动服务路由。但是为了避免您之前遇到的“缺少控制器”错误,请添加 MVC 路由 with Route Constraint。这些路由约束可以是正则表达式——基本上你希望你的路由约束是任何 不是“服务”的控制器。当请求“服务”请求时,它会通过 WCF 服务路由。

    【讨论】:

    • 谢谢!我使用new { controller = "^{?!Service}"} 作为约束,它就像一个魅力。你明白为什么服务路由不能在 MVC 路由之前吗?
    • {controller} 和 {action} 标记是始终隐含在 MVC 中的特殊标记(您也可以定义自己的标记,但它们总是在那里)。当您首先放置服务路由时,它无法在您为路由定义的模式中的任何位置找到这些标记,因此它只是将它们作为查询字符串附加。因此,当服务路线首先出现时,它会变得非常混乱。通常,您希望对路线进行排序,以便首先定义最“具体”的路线。很高兴听到它现在对你有用。
    • 谢谢,这很有帮助。更正未来的谷歌人:我使用的模式实际上是^(?!Service).*
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 2013-07-09
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多