2011-10-15 78 views
5

也許我不明白MVC地區的工作方式,但這讓我有些困惑。ASP.NET MVC3區域控制器可從全球路線訪問?

  1. 添加一個名爲「MyArea」使用區域單擊右鍵,在Visual Studio中的「添加區」關於MVC3項目
  2. 創建MyArea控制器:「AnArea」與在MyArea區域匹配視圖。
  3. 添加「控制器=‘AnArea’在MyAreaAreaRegistration.RegisterArea方法context.MapRoute的默認參數。

所以在這一點,如果你啓動應用程序,並導航到/ MyArea /它應該加載與AnArea控制器它匹配視圖如果您導航到/ MyArea/AnArea,它會顯示同樣的結果

但是,如果你瀏覽到/ AnArea /,控制器仍然發現並顯示以下錯誤消息:。

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/anarea/Index.aspx 
~/Views/anarea/Index.ascx 
~/Views/Shared/Index.aspx 
~/Views/Shared/Index.ascx 
~/Views/anarea/Index.cshtml 
~/Views/anarea/Index.vbhtml 
~/Views/Shared/Index.cshtml 
~/Views/Shared/Index.vbhtml 

這是正確的行爲嗎?我原以爲區域的控制器只能通過它自己的區域訪問,而不是全局的。

+0

可能出現的[ASP.NET MVC默認路由可以通過區域路由訪問]重複(http://stackoverflow.com/questions/4612279/asp-net-mvc-default-routes-accessible-via-area-routes) –

回答

6

每當我創建一個區域項目,我改變我的Default路線如下:

routes.MapRoute( 
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults 
     null, // constraints 
     new string[] { "MyApplication.Controllers" } // namespaces 
    ); 

最後一個參數限制的默認路由在MyApplication.Controllers命名空間中的控制器。這確保了默認路由僅限於任何區域以外的操作。

UPDATE

深入瞭解代碼後,我發現其中的問題出現,並有一個解決方案。你的默認路由更改爲以下:

routes.Add(
    "Default", 
    new Route("{controller}/{action}/{id}", 
     new RouteValueDictionary(
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ), 
     null, 
     new RouteValueDictionary(
      new { 
       Namespaces = new string[] { "MyApplication.Controllers" }, 
       UseNamespaceFallback = false 
      } 
     ), 
     new MvcRouteHandler() 
    ) 
); 

關鍵是在加入UseNamespaceFallback令牌。這將阻止Default路由查看任何其他名稱空間。

這是意想不到的行爲,這是一個問題,我不知道哪些會影響我正在進行的項目。我將在aspnet.codeplex.com上列出它作爲問題。我不會將這稱爲一個錯誤,但行爲絕對會違反MVC路由的召喚。

+0

這似乎不起作用,區域控制器仍然通過/ anarea/ 激活我的控制器駐留在名稱空間: (這是創建新項目時放置HomeController的地方) – Duane

+0

您是否在Global.asax.cs中定義了其他任何路由? – counsellorben

+0

沒有,只有 「默認」 與你在你的答案提出的修改路線: routes.MapRoute( 「默認」,//路線名稱 「{控制器}/{行動}/{ID}」,//具有參數的URL new {controller =「Home」,action =「Index」,id = UrlParameter.Optional},//參數默認值 null,//約束 new [] {「TestAreaControllerAccessibleFromGlobal.Controllers」} //命名空間 ); – Duane

0

您必須在區域和一般路線中應用命名空間限制。

在的global.asax.cs你應該修改的RegisterRoutes方法就這樣

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
    routes.MapRoute(
     "Default", 
     "{controller}/{action}/{id}", 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
     new string[] { "MyProject.Controllers" } 
    ); 
} 

這將限制 「//」 才命名空間 「MyProject.Controllers」

而且you'll必須將名稱空間限制應用於區域以將「//」僅限制爲名稱空間「MyProject.Areas.MyArea.Controllers」

爲此,您必須編輯「MyAreaAreaRegistration.cs」的「RegisterArea」方法,像下面一樣(「MyAreaRegistration。CS」位於‘/ MyProject的/地區/ MyArea’文件夾):

//Some default code stuff 
... 
public override void RegisterArea(AreaRegistrationContext context) 
{ 
    context.MapRoute(
     "MyArea_default", 
     "MyArea/{controller}/{action}/{id}", 
     new { action = "Index", id = UrlParameter.Optional }, 
     new string[] { "MyProject.Areas.MyArea.Controllers" } 
    ); 
} 

希望它可以幫助!

+0

必須缺少一些東西,我創建了一個新的MVC3項目,添加了一個名爲MyArea的新區域,進行了上述更改,但是Area的控制器仍然可以從全局中看到... ie // AreaHome調用命名空間「MyProject.Areas.MyArea.Controllers」中的/ MyArea/Controllers/AreaHomeController。 – Duane

0

你似乎是導航到/AnArea,而你的區域被稱爲MyArea所以你應該轉到。/MyArea/這裏的區域航線登記的樣子:

context.MapRoute(
    "MyArea_default", 
    "MyArea/{controller}/{action}/{id}", 
    new { controller = "AnArea", action = "Index", id = UrlParameter.Optional } 
); 

AnArea是控制器,而不是區域的名稱如果要導航到這個區域,你應該總是前綴的一些控制你的網址爲MyArea,這是該地區的名稱。

+0

我明白這一點,我很好奇的行爲是如何停止/ AnArea /解決MyArea的AnArea控制器。看來counsellerben已經找到了解決方案,所以非常感謝 – Duane