2016-01-14 91 views
1

在我的MVC項目中,我有項目控制器和一些動作如索引MVC RouteConfig影響Html.ActionLink()輔助方法

的RouteConfig包括:

routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 

在一些觀點,我使用的輔助方法Html.ActionLink( 「項目」, 「索引」, 「項目」)創建索引錨行動。所以錨結果HREF會(/項目/指標

現在,我需要映射以下靜態網址:

/IndirectItem /索引

索引動作項目控制器默認參數(間接=真),所以RouteConfig將是:

routes.MapRoute(
       name: "IndirectItem", 
       url: "IndirectItem/Index", 
       defaults: new { controller = "Item", action = "Index", indirect = true } 
      ); 
    routes.MapRoute(
       name: "Default", 
       url: "{controller}/{action}/{id}", 
       defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 

看來OK和客戶端的請求被正確映射,但所有錨導致從Html.ActionLink(「項目」,「索引」, 「Item」)輔助方法映射到URL(/IndirectItem/Index)而不是(/Item/Index)。

我怎麼能解決這個問題,在不改變所有Html.ActionLink()Html.RouteLink()或添加另一條路線爲原來的網址是什麼?

回答

1

使用約束將是你的問題一個方便的解決方案。

使用以下IndirectItem路線而不是您的路線。

routes.MapRoute(
      name: "IndirectItem", 
      url: "{staticVar}/{action}", 
      defaults: new { controller = "Item", action = "Index", indirect = true}, 
      constraints: new { staticVar = "IndirectItem" } 
     ); 

,你不需要在默認路線的任何變化。

它適用於我。

+1

非常好的解決方案。這是一個可以應用於多種行動的動態路線。謝謝。 –

+0

很高興,因爲你得到它的工作:)) –

0

您遇到這個問題,因爲Html.ActionLink使用路由表中生成URL和自IndirectItem路線是匹配Html.ActionLink("Items","Index","Item")(因爲它有指標作用,並在這兩個路線和動作鏈接指定項目控制器)。解析由第一場比賽做了路線登記的先後順序重要

通過添加DefaultItem路線:

當前的路線之前
routes.MapRoute(
    name: "DefaultItem", 
    url: "Item/Index/{id}", 
    defaults: new { controller = "Item", action = "Index", id = UrlParameter.Optional } 
); 

routes.MapRoute(
     name: "IndirectItem", 
     url: "IndirectItem/Index/, 
     defaults: new { controller = "Item", action = "Index", indirect = true} 
); 
routes.MapRoute(
     name: "Default", 
     url: "{controller}/{action}/{id}", 
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

應該解決的問題

另一種選擇是創建從Item控制器繼承的空IndirectItem控制器:

public IndirectItemController : ItemController 
{ 
} 

,然後改變路線

routes.MapRoute(
     name: "IndirectItem", 
     url: "IndirectItem/Index/, 
     defaults: new { controller = "IndirectItem", action = "Index", indirect = true} 
); 
+0

我已經嘗試了第一個解決方案,但是我發現更改的效果會很好,因爲相同的方案將應用於多個控制器。 我認爲第二個解決方案是一個很好的解決方案。謝謝。 –

0

Omar Gohar和Alex Art給出的答案有誤導性。

您遇到的問題是您的路線不匹配時生成的網址。這很簡單,因爲您尚未提供所有路線值以在您的ActionLink中創建匹配項。

@Html.ActionLink("Items", "Index", "Item", new { indirect = true }, null) 

如果更改ActionLink聲明不是一個選項,您可以將您"indirect"元數據使用DataTokens parameter附加到路徑。

您使用DataTokens屬性檢索或分配與被不用於確定路由是否一個URL模式匹配的路由相關的值。這些值被傳遞給路由處理程序,它們可以用於處理請求。

routes.MapRoute(
    name: "IndirectItem", 
    url: "IndirectItem/Index", 
    defaults: new { controller = "Item", action = "Index" } 
).DataTokens = new RouteValueDictionary(new { indirect = true }); 

的底線是RouteValues(其由默認值填充如果不是由URL圖案提供)並不意在用於元數據。它們的目的是成爲真正的數據來匹配使URL獨一無二。

當然,如果您實際上沒有使用indirect路由值,您可以簡單地將它從路由中省略。

routes.MapRoute(
    name: "IndirectItem", 
    url: "IndirectItem/Index", 
    defaults: new { controller = "Item", action = "Index" } 
);