26

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

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

4

3 回答 3

19

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

于 2010-08-26T03:41:04.637 回答
9

我解决了这个问题:

     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)));

我希望这对你有好处

于 2012-06-03T00:05:43.283 回答
3

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

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;
    }
}

这样,反向路由映射永远不会为任何操作选择此路由。奇迹般有效

于 2011-06-29T07:30:08.387 回答