2013-12-09 89 views
41

場景:我在ASP.NET MVC 5站點中有一個Forms區域。屬性路由不在區域工作

我在嘗試重定向到使用新的屬性路由功能定義的自定義路由的詳細操作。

的RedirectToAction:

return RedirectToAction("Details", new { slug }); 

我重定向到行動:

[HttpGet] 
[Route("forms/{slug}")] 
public ActionResult Details(string slug) 
{ 
    var form = FormRepository.Get(slug); 

    ... 

    return View(model); 
} 

我希望重定向到http://localhost/forms/my-slug而是應用程序被重定向我http://localhost/Forms/Details?slug=my-slug

這意味着屬性路由不起作用。

這怎麼解決?

我已經添加了routes.MapMvcAttributeRoutes();行我RouteConfig:

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

     routes.MapMvcAttributeRoutes(); 

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

而且這裏是我的Application_Start():

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 
    BundleConfig.RegisterBundles(BundleTable.Bundles); 
} 

回答

77

你可能合併約定的路由與屬性的路由,你應該註冊區域後,您映射屬性的路由

AreaRegistration.RegisterAllAreas(); 

應該被稱爲該行後:

routes.MapMvcAttributeRoutes(); 

解釋(來自http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areas):

如果您使用的是帶有路由屬性這兩個領域,以及具有基於會議的路線的區域(由AreaRegistration類設置),那麼您需要確保該區域註冊離子發生在配置了MVC屬性路由之後,但是在默認基於約定的路由被設置之前。原因是路由註冊應該從最具體的(屬性)通過更一般的(區域註冊)到薄霧通用(默認路由)進行排序,以避免通用路由通過匹配傳入的請求而過早地「隱藏」更具體的路由管道。

當你創建一個空白asp.net的MVC網站,添加一個區域,並開始使用屬性的路由,你會遇到這樣的問題,因爲在Visual Studio中的「添加區」操作會將RegisterAllAreas在你的Application_Start打電話,前該路由配置..

替代解決方案

也許你不打算使用基於約定的路由,以保持和寧願是隻使用屬性的路由。 在這種情況下,您可以刪除FormsAreaRegistration.cs文件。

+1

SWEET!花了將近4個小時試圖找出MVC 5.1之後的這個愚蠢的改變之後,您的解決方案一勞永逸地解決了我的問題。 – Korayem

+0

我很高興我的問題+答案已經幫助了很多人:-) –

+2

這對我有效..我放棄了區域路線屬性,因爲它根本行不通。但是,在Route.MapMvcAttributeRoutes()之後移動AreaRegistration.RegisterAllAreas()之後,它神奇地做了這個訣竅! –

34

將AreaRegistration.RegisterAllAreas()移動到RouteConfig.cs對我來說還不夠。我還需要使用AreaPrefix參數爲RouteArea attibute:

//Use the named parameter "AreaPrefix" 
[RouteArea("AreaName", AreaPrefix = "area-name-in-url")] 
[RoutePrefix("controller-name-in-url")] 
public class SampleController : Controller 
{ 
    [Route("{actionParameter}")] 
    public ActionResult Index(string actionParameter) 
    { 
     return View(); 
    } 
} 

編輯:在某一點上,我對面微軟樣本的解決方案,很好地展示瞭如何處理屬性的路由來了。它還展示了一些很好的例子,說明如何將SelectList轉換爲input[type="radio"]項目的數組,以及對input[type="checkbox"]項目(如果我記得)進行相同操作。這個示例解決方案可能是對這個問題的更好回答 - 以及在顯示單選按鈕和複選框項目時給出一些很好的示例。如果有人知道這個示例解決方案,請添加一個帶有鏈接的評論。

+0

如果沒有這個,視圖引擎能夠正確地推斷出我的視圖的位置。 –

+3

我還需要AreaPrefix,即使它只是AreaPrefix =「」(.NET 4.6.1應用程序,沒有其他地區/文件夾具有相同的名稱,所以沒有歧義) – jspinella