2013-12-09 10 views
41

Szenario: Ich habe einen Formularbereich in meiner ASP.NET MVC 5-Site.Attribut-Routing funktioniert nicht in Bereichen

Ich versuche, auf die Details Action umzuleiten, die eine benutzerdefinierte Route verwendet, die mit der neuen Attribut-Routing-Funktion definiert wurde.

Die RedirectToAction:

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

Die Aktion ich bin Umleitung:

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

    ... 

    return View(model); 
} 

Ich würde eine Umleitung zu http://localhost/forms/my-slug erwarten, sondern die App mich http://localhost/Forms/Details?slug=my-slug wird umgeleitet wird.

Dies bedeutet, dass das Attribut Routing nicht funktioniert.

Wie kann das gelöst werden?

Ich habe die routes.MapMvcAttributeRoutes() hinzugefügt; Linie meiner 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 } 
     ); 
    } 
} 

Und hier ist mein Application_Start():

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

Antwort

77

Sie sind wahrscheinlich mit dem Attribut Routing-Konvention basiertes Routing kombiniert, und Sie sollten Ihre Bereiche registrieren, nachdem Sie die Attribut Routen Karte.

routes.MapMvcAttributeRoutes(); 

Die Erklärung (von http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areas):

Die Linie

AreaRegistration.RegisterAllAreas(); 

sollte nach dieser Zeile genannt werden

Wenn Sie mit beiden Bereichen mit Streckenattribute, und Bereiche mit konventionsbasierten Routen (festgelegt durch eine AreaRegistration-Klasse), dann müssen Sie sicherstellen, dass die Bereichsregistrierung erfolgt Nachdem die MVC-Attributrouten konfiguriert wurden, jedoch bevor die standardkonventionelle Route festgelegt wurde, treten sie auf. Der Grund dafür ist, dass die Routenregistrierung von den spezifischsten (Attributen) über die allgemeine (Bereichsregistrierung) bis zum generischen Standard (die Standardroute) sortiert werden sollte, um zu verhindern, dass generische Routen spezifischere Routen "ausblenden", indem sie eingehende Anfragen zu früh abgleichen die Pipeline.

Wenn Sie eine leere asp.net Mvc Website erstellen, einen Bereich hinzufügen und starten Attribut-Routing verwenden, werden Sie dieses Problem auftritt, weil die „Area hinzufügen“ Aktion in Visual Studio die RegisterAllAreas in Ihrem Application_Start nennen fügt hinzu, bevor die Route Konfiguration ..

Alternative Lösung

Vielleicht wollen Sie nicht nur auf die Verwendung Attribut-Routing Konvention based Routing zu halten und es vorziehen. In diesem Fall können Sie einfach die Datei FormsAreaRegistration.cs löschen.

+1

SWEET! Nachdem ich fast 4 Stunden damit verbracht habe, diese blöde Veränderung in MVC 5.1 herauszufinden, löst Ihre Lösung mein Problem ein für allemal. – Korayem

+0

Ich bin froh, dass meine Frage + Antwort so vielen Menschen im Laufe der Zeit geholfen hat :-) –

+2

Dies funktionierte für mich .. Ich hatte Area Route Attribute aufgegeben, weil es einfach nicht funktionieren würde. Aber nachdem ich AreaRegistration.RegisterAllAreas() nach routes.MapMvcAttributeRoutes() verschoben habe, hat es auf magische Weise den Trick geschafft! –

34

Das Verschieben der AreaRegister.RegisterAllAreas() auf RouteConfig.cs war nicht genug für mich.Ich musste auch die AREAPREFIX Parameter für die RouteArea attibute verwenden:

//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: Irgendwann ich auf einer Probenlösung von Microsoft kam, die sich gut gezeigt, wie Routing umgehen Attribut. Es zeigte auch einige nette Beispiele, wie man ein SelectList in ein Array von input[type="radio"] Items übersetzt und dasselbe mit einem Array von input[type="checkbox"] Items macht (wenn ich mich erinnere). Diese Beispiellösung ist wahrscheinlich eine bessere Antwort auf diese Frage - und gibt einige gute Beispiele für die Anzeige von Optionsfeldern und Kontrollkästchen. Wenn jemand von dieser Beispiellösung weiß, fügen Sie bitte einen Kommentar mit einem Link dazu hinzu.

+0

Ohne diese konnte die View-Engine den Standort meiner Sicht richtig ableiten. –

+3

Ich brauchte auch AreaPrefix, auch wenn es nur AreaPrefix = "" war (.NET 4.6.1 App, keine anderen Bereiche/Ordner mit demselben Namen, also keine Mehrdeutigkeit) – jspinella