2010-08-25 50 views
25

我有一個與MVC2網站並排生活的WCF服務。我想爲我的URL的服務看起來像這樣:MVC2路由與WCF ServiceRoute:Html.ActionLink渲染不正確的鏈接!

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/並進入正確的頁面。

我在做什麼非常明顯的新手錯誤?

+0

可能有關? http://stackoverflow.com/questions/1470997/html-actionlink-construct-wrong-link-when-a-non-mvc-route-is-added – roufamatic 2010-08-26 00:01:07

回答

18

嘗試移動服務路線之後的MVC路線。但爲了避免之前獲得的「缺失控制器」錯誤,請將MVC路線 a Route Constraint相加。這些路由約束可以是正則表達式 - 基本上你會希望你的路由約束是而不是「服務」的任何控制器。當請求「服務」請求時,它將使其通過和他的WCF服務路由。

+2

謝謝!我用'new {controller =「^ {?! Service}」}'作爲約束條件,它像一個魅力一樣工作。你明白爲什麼服務路線不能在MVC路線之前? – roufamatic 2010-08-26 04:53:25

+0

{controller}和{action}令牌是MVC中始終隱含的特殊令牌(您也可以定義自己的令牌,但這些令牌總是*那裏)。當您首先放置服務路線時,它無法在您爲路線定義的模式中的任何位置找到這些標記,因此它只是將它們附加爲查詢字符串。因此,當服務路線第一時,它就變得非常混亂。通常,您要訂購路線,以便首先定義最「特定」的路線。很高興聽到它現在適合你。 – 2010-08-26 11:16:04

+5

謝謝,這很有幫助。更正未來的谷歌搜索引擎:我使用的模式其實是'^(?!服務)。''' – roufamatic 2010-08-26 21:25:14

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

這種方式,反向路由映射從未選擇任何行動這條路線。就像一個魅力

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

我希望這對你有好處

+0

優秀 - 我完全忘記了那些過濾器!謝謝! – 2013-05-18 02:16:34