2011-10-15 13 views
5

Być może nie rozumiem poprawnie działania obszarów MVC, ale to mnie trochę zdezorientowało.ASP.NET MVC3 Kontroler obszaru dostępny z tras globalnych?

  1. Dodaj obszaru nazywanego "MyArea" przy użyciu prawym przyciskiem "Add Area" w Visual Studio przy projekcie MVC3
  2. Tworzenie kontrolera dla MyArea: "AnArea" dopasowane widok w obszarze MyArea.
  3. Add „controller =«AnArea»do wartości domyślnych parametrów context.MapRoute w metodzie MyAreaAreaRegistration.RegisterArea.

Więc w tym momencie, jeśli uruchomić aplikację i przejdź do/MyArea/należy załadować sterownik AnArea z to dopasowanie widoku Jeśli przejdź do/MyArea/AnArea, pokaże ten sam rezultat

Ale jeśli przejdź do/AnArea/sterownik jest nadal obecny i wyświetlany jest następujący komunikat o błędzie:..

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 

Czy to jest prawidłowe zachowanie? Myślałem, że kontroler obszaru może być dostępny tylko przez jego własny obszar, a nie globalnie.

+0

możliwy duplikat [ASP.NET MVC Domyślne trasy dostępne przez trasy obszaru] (http://stackoverflow.com/questions/4612279/asp-net-mvc-default-routes-accessible-via-area-routes) –

Odpowiedz

6

Ilekroć utworzyć projekt z obszarów, mogę zmienić Default trasę w następujący sposób:

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

Końcowy parametr ogranicza domyślną trasę do sterowników w przestrzeni nazw MyApplication.Controllers. Zapewnia to, że trasa domyślna jest ograniczona do działań spoza jakichkolwiek obszarów.

UPDATE

Po głębokim nurkowaniu do kodu, odkryłem, gdzie pojawia się problem, i ma rozwiązanie. Zmienić domyślną trasę do:

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

Kluczem jest dodanie UseNamespaceFallback token. Spowoduje to, że trasa domyślna nie będzie zaglądać do żadnych innych obszarów nazw.

Jest to nieoczekiwane zachowanie i był to problem, o którym nie wiedziałem, który wpływa na projekt, nad którym pracuję. Wypisuję to jako problem na stronie aspnet.codeplex.com. Nie nazwałbym tego błędem, ale zachowanie zdecydowanie wydaje się naruszać konwencje dotyczące routingu MVC.

+0

To wydaje się nie działać, kontroler obszaru jest wciąż aktywowany przez/anarea/ Mój kontroler rezyduje w przestrzeni nazw: TestAreaControllerAccessibleFromGlobal.Areas.MyArea.Controllers, i dodałem przestrzeń nazw "TestAreaControllerAccessibleFromGlobal.Controllers" do domyślnej rejestracji trasy (w tym miejscu został umieszczony HomeController podczas tworzenia nowego projektu) – Duane

+0

Czy posiadasz inne trasy zdefiniowane w Global.asax.cs? – counsellorben

+0

Nie, tylko trasa "domyślna" z modyfikacjami sugerowanymi w odpowiedzi: routes.MapRoute ( "Default", // nazwa trasy "{controller}/{action}/{id}", // URL o parametrach nowy {kontroler = "Strona główna", akcja = "Indeks", id = UrlParameter.Optional}, // Parametr domyślny null, // ograniczenia new [] {"TestAreaControllerAccessibleFromGlobal.Controllers"} // namespaces ); – Duane

0

Musisz zastosować ograniczenie przestrzeni nazw zarówno na obszarze, jak i na trasie głównej.

W Global.asax.cs należy edytować RegisterRoutes metody podobnie jak ten

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

To będzie ograniczać "//" tylko do przestrzeni nazw "MyProject.Controllers"

Ale także you'll musisz zastosować ograniczenie przestrzeni nazw do obszaru, aby ograniczyć "//" tylko do przestrzeni nazw "MyProject.Areas.MyArea.Controllers"

W tym celu musisz edytować metodę "RegisterArea" w pliku "MyAreaAreaRegistration.cs" jak poniżej ("MojaAreaRegistration.cs”znajduje się na«/ myproject/regiony/MyArea folderu»):

//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" } 
    ); 
} 

Nadzieja pomaga !!

+0

Coś musi być nie tak, stworzyłem nowy projekt MVC3, dodałem nowy obszar o nazwie MyArea, wprowadziłem powyższe zmiany, które zasugerowałeś, ale kontroler obszaru jest nadal widoczny z globalnego ... tzn. // AreaHome wywołuje funkcję/MyArea/Controllers/AreaHomeController w przestrzeni nazw "MyProject.Areas.MyArea.Controllers". – Duane

0

Wydaje się, że przechodząc do /AnArea natomiast danym obszarze jest nazywany MyArea więc należy przejść do . /MyArea/ Oto jak rejestracja trasy obszar wygląda.

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

AnArea to nazwa kontrolera, a nie okolicy, jeśli chcesz, aby przejść do jakiegoś kontrolera tej dziedzinie powinny zawsze poprzedź swoje adres URL z numerem MyArea, który jest nazwą obszaru.

+0

Rozumiem, że zachowanie, które mnie interesuje, polega na tym, jak zatrzymać/AnArea/z rozłożenia na kontroler AnArea MyArea. Wygląda na to, że counsellerben znalazł rozwiązanie, więc dzięki – Duane

Powiązane problemy