2013-12-09 13 views
41

Scenariusz: Mam obszar formularzy w mojej witrynie ASP.NET MVC 5.Atrybut Routing nie działa w obszarach

Próbuję przekierować do akcji szczegółów, która używa niestandardowej trasy zdefiniowanej przy użyciu nowej funkcji wyznaczania atrybutu.

RedirectToAction:

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

Akcja mam skierowanie do:

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

    ... 

    return View(model); 
} 

spodziewałbym przekierowanie do http://localhost/forms/my-slug lecz aplikacja przekierowuje mnie do http://localhost/Forms/Details?slug=my-slug.

Oznacza to, że routing atrybutów nie działa.

Jak można to rozwiązać?

Dodałem route.MapMvcAttributeRoutes(); Linia do mojego 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 } 
     ); 
    } 
} 

A oto moja Application_Start():

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

Odpowiedz

77

Prawdopodobnie łącząc konwencja routing w oparciu o routing atrybutu i należy zarejestrować obszary po mapę trasy atrybutów.

Linia

AreaRegistration.RegisterAllAreas(); 

powinna nazywać się po tej linii:

routes.MapMvcAttributeRoutes(); 

Wyjaśnienie (od http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areas):

Jeśli używasz obu obszarach z atrybutami trasy, i obszary z trasami opartymi na konwencjach (ustawione przez klasę AreaRegistration), następnie musisz upewnić się, że rejestracja obszaru dzieje się po skonfigurowaniu tras atrybutów MVC, jednak przed ustawieniem domyślnej trasy opartej na konwencji. Powodem jest to, że rejestracja trasy powinna być zamawiana od najbardziej szczegółowych (atrybutów) poprzez bardziej ogólną (rejestracja obszaru) do generic mgły (domyślna trasa), aby uniknąć generowania tras od "ukrywania" bardziej specyficznych tras przez dopasowywanie przychodzących żądań zbyt wcześnie rurociągu.

Po utworzeniu pustej ASP.NET MVC stronę, dodać obszar i zacząć używać routingu atrybutu, można spotkać ten problem, ponieważ „Dodaj obszar” działanie w visual studio dodaje RegisterAllAreas zadzwonić w Application_Start, zanim konfiguracja trasy ..

rozwiązanie Alternatywa

Może nie zamierzają nadal korzystać konwencja opiera się routing i wolą do użytku trasy atrybutów. W takim przypadku możesz po prostu usunąć plik FormsAreaRegistration.cs.

+1

SŁODKA! po spędzeniu prawie 4 godzin próbując rozgryźć tę głupią zmianę w MVC 5.1, twoje rozwiązanie rozwiązuje mój problem raz na zawsze. – Korayem

+0

Cieszę się, że moje pytanie + odpowiedź pomogło tak wielu ludziom na czas :-) –

+2

To zadziałało dla mnie .. Porzuciłem atrybuty trasy obszaru, ponieważ po prostu nie działałoby. Ale po przeniesieniu AreaRegistration.RegisterAllAreas() po routes.MapMvcAttributeRoutes(), to magicznie udało się! –

34

Przeniesienie funkcji AreaRegistration.RegisterAllAreas() na RouteConfig.cs nie było dla mnie wystarczające.Musiałem także użyć parametru AreaPrefix dla attibute RouteArea:

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

Edit: W pewnym momencie natknąłem się roztworu próbki z Microsoft, który ładnie pokazał, jak obsługiwać routing atrybutów. Pokazano również kilka ładnych przykładów przetłumaczenia SelectList na tablicę z elementami input[type="radio"], a także na to samo z tablicą elementów input[type="checkbox"] (jeśli sobie przypomnę). To przykładowe rozwiązanie jest prawdopodobnie lepszą odpowiedzią na to pytanie - a także daje kilka dobrych przykładów na wyświetlanie przycisków radiowych i pozycji w polu wyboru. Jeśli ktoś wie o tym przykładowym rozwiązaniu, dodaj komentarz z linkiem do niego.

+0

Bez tego mechanizm wyświetlania mógł poprawnie określić położenie mojego widoku. –

+3

Potrzebowałem również AreaPrefix, nawet jeśli był to tylko AreaPrefix = "" (aplikacja .NET 4.6.1, brak innych obszarów/folderów o tej samej nazwie, więc nie ma dwuznaczności) – jspinella

Powiązane problemy