2014-05-21 9 views
5

Sto usando il MVC Attributo Routing (MVC 5.1.2) e sono in esecuzione in errore:MVC AttributeRoute sembra essere ignorando RoutePrefix e causando l'azione corrispondenti a mutiple Controller errore

Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.

The request has found the following matching controller types: FFInfo.WebUI.Areas.Admin.Controllers.HomeController FFInfo.WebUI.Areas.Admin.Controllers.SectionController

Questo accade solo quando ho vai a /Admin/Sections/ e non sono sicuro del perché, poiché esiste una sola route che può corrispondere a quell'URL, qualcuno può aiutarmi a capire cosa c'è che non va? Si noti che questo problema è esclusivo di 5.1.2, MVC 5.0 funziona correttamente.

controller Base:

[RouteArea("Admin")] 
public class BaseController : Controller 
{ 
} 

controller casa:

[RoutePrefix("")] 
[Route("{action}")] 
public class HomeController : BaseController 
{ 

    public ActionResult Index() 
    { 
    } 

    public ActionResult Updates() 
    { 
    } 

    [ChildActionOnly] 
    public PartialViewResult GetUpdatesGrid() 
    { 
    } 


    public ActionResult GetUpdates(JqGridRequest Request) 
    { 
    } 
} 

Sezione Controller:

[RoutePrefix("Sections")] 
[Route("{action}")] 
public class SectionController : BaseController 
{ 
    [Route] 
    public ActionResult Sections() 
    { 
    } 

    [ChildActionOnly] 
    public PartialViewResult GetSectionsGrid() 
    { 
    } 

    public ActionResult GetSections(JqGridRequest Request) 
    { 
    } 

    public ActionResult AddSection() 
    { 
    } 

    [HttpPost, ValidateAntiForgeryToken] 
    public ActionResult AddSection(AddEditSectionVM model, HttpPostedFileBase LogoFile) 
    { 
    } 

    public ActionResult EditSection(Int16? ID) 
    { 
    } 

    [HttpPost, ValidateAntiForgeryToken] 
    public ActionResult EditSection(AddEditSectionVM model, HttpPostedFileBase Logo) 
    { 
    } 

    public ActionResult Releases() 
    { 
    } 

    [ChildActionOnly] 
    public PartialViewResult GetReleasesGrid() 
    { 
    } 

    public ActionResult GetReleases(JqGridRequest Request) 
    { 
    } 

    public ActionResult AddRelease() 
    { 
    } 

    [HttpPost, ValidateAntiForgeryToken] 
    public ActionResult AddRelease(AddEditReleaseVM model) 
    { 
    } 
} 

La mia comprensione del RouteAreaRoutePrefix, e Route attributi mi dice che /Admin/Index chiamerà il IndexActionResult del controller principale e l'URL Admin/Sections devono chiamare IndexActionResult del controller sezioni. Tutte le altre rotte funzionano perfettamente bene in ogni controller e quando si va su /Admin/Index funziona perfettamente. Ho ricevuto questo errore solo quando vado a /Admin/Sections. Che c'è?

risposta

7

Questo sembra essere un effetto collaterale di una modifica sostanziale in ASP.Net MVC 5.1 relative a come attributo di routing gestisce le possibili corrispondenze ambigue: http://www.asp.net/mvc/overview/releases/mvc51-release-notes

abbiamo incontrato problemi simili quando si aggiorna dal 5,0 al corrente 5.1.2. Sembra che le rotte nidificate come questa funzionino in base alla vecchia logica e ora falliscono a causa del severo cambiamento.

Nel tuo esempio,/Admin/Index potrebbe corrispondere tecnicamente sul HomeController poiché potrebbe essere interpretato come/{area = Amministratore}/{azione = Indice}. Non sembra che ci sia una logica speciale (o almeno, sembra che non ci sia più) che cerca di vedere se il segmento {action} accade per abbinare un RoutePrefix definito su un controller alternativo nella stessa Area.

Questo sembra rendere non più possibili percorsi nidificati come questo, poiché è necessario aggiungere un RoutePrefix definito come "Casa" a HomeController per distinguere tra le corrispondenze del percorso del controller. Forse questo è risolvibile tramite un RouteConstraint o un altro meccanismo, ma non sono ancora riuscito a trovare una soluzione.

+1

C'è stato un cambio di interruzione da 5.0 a 5.1 Ho aperto un bug ticket e ho avuto la risposta che "funzionava come progettato". – Matthew

+1

Sicuramente NON "funziona come progettato" –

0

Sto pensando che è necessario cambiare il [Route({action})] su ciascun controller su [Route({action=Index})].

Inoltre, hai menzionato l'azione Index sul tuo SectionController, ma non la vedo nel tuo codice. Vedo però che hai un'azione Sections che ha [Route] elencato sopra. Immagino che l'azione Sections sia effettivamente quella a cui si desidera accedere quando si passa a /Admin/Sections, nel qual caso è necessario rimuovere [Route] sull'azione Sections e modificare lo [Route({action})] su SectionController su [Route({action=Sections})].

Spero che questo aiuti.;)