使用WCF ServiceRoute的MVC2路由:Html.ActionLink呈现错误的链接!

时间:2010-08-25 23:03:00

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

我有一个与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/并进入正确的页面。

我制作了一个非常明显的新手错误?

3 个答案:

答案 0 :(得分:18)

尝试在 MVC路由后移动服务路径。但是为了避免之前遇到的“丢失控制器”错误,请使用 a Route Constraint添加MVC路由。这些路由约束可以是Regex - 基本上你希望你的路由约束是“Service”的任何控制器。当请求“服务”请求时,它将使其失效并且是他的WCF服务路由。

答案 1 :(得分:8)

我解决了这个问题:

     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 :(得分:3)

另一种解决方案是继承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;
    }
}

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