Asp.net mvc 5 MVC AttributeRoute似乎忽略了RoutePrefix,并在多个控制器错误中导致匹配操作

Asp.net mvc 5 MVC AttributeRoute似乎忽略了RoutePrefix,并在多个控制器错误中导致匹配操作,asp.net-mvc-5,attributerouting,Asp.net Mvc 5,Attributerouting,我正在使用MVC属性路由(MVC 5.1.2),遇到以下错误: 找到多个与URL匹配的控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则可能发生这种情况 请求已找到以下匹配的控制器类型: FFInfo.WebUI.Areas.Admin.Controllers.HomeController FFInfo.WebUI.Areas.Admin.Controllers.SectionController 只有当我转到/Admin/Sections/时才会发生这种情况,我真的不知道为什么,因为

我正在使用MVC属性路由(MVC 5.1.2),遇到以下错误:

找到多个与URL匹配的控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则可能发生这种情况

请求已找到以下匹配的控制器类型: FFInfo.WebUI.Areas.Admin.Controllers.HomeController FFInfo.WebUI.Areas.Admin.Controllers.SectionController

只有当我转到
/Admin/Sections/
时才会发生这种情况,我真的不知道为什么,因为只有一条路径可以匹配该URL,有人能帮我找出问题所在吗?请注意,这个问题是5.1.2、MVC 5.0独有的,它可以正常工作

基本控制器:

[RouteArea("Admin")]
public class BaseController : Controller
{
}
[RoutePrefix("")]
[Route("{action}")]
public class HomeController : BaseController
{
    
    public ActionResult Index()
    {
    }

    public ActionResult Updates()
    {
    }

    [ChildActionOnly]
    public PartialViewResult GetUpdatesGrid()
    {
    }

    
    public ActionResult GetUpdates(JqGridRequest Request)
    {
    }
}
[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)
    {
    }
}
家庭控制器:

[RouteArea("Admin")]
public class BaseController : Controller
{
}
[RoutePrefix("")]
[Route("{action}")]
public class HomeController : BaseController
{
    
    public ActionResult Index()
    {
    }

    public ActionResult Updates()
    {
    }

    [ChildActionOnly]
    public PartialViewResult GetUpdatesGrid()
    {
    }

    
    public ActionResult GetUpdates(JqGridRequest Request)
    {
    }
}
[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)
    {
    }
}
分区控制员:

[RouteArea("Admin")]
public class BaseController : Controller
{
}
[RoutePrefix("")]
[Route("{action}")]
public class HomeController : BaseController
{
    
    public ActionResult Index()
    {
    }

    public ActionResult Updates()
    {
    }

    [ChildActionOnly]
    public PartialViewResult GetUpdatesGrid()
    {
    }

    
    public ActionResult GetUpdates(JqGridRequest Request)
    {
    }
}
[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)
    {
    }
}

我对
RouteArea
RoutePrefix
的理解,和
路由
属性告诉我
/Admin/Index
将调用主控制器的
索引
操作结果
,URL
管理员/Sections
应调用Sections控制器的
索引
操作结果。所有其他路由在每个控制器中都可以正常工作,当您转到
/Admin/Index
时,工作正常。我只有在转到
/Admin/Sections
时才会出现此错误。怎么了?

这似乎是ASP.Net MVC 5.1中与属性路由如何处理潜在不明确匹配相关的突破性更改的副作用:

从5.0更新到当前的5.1.2时,我们遇到了类似的问题。看起来像这样的嵌套路由恰好是基于旧逻辑工作的,而现在由于严格的中断更改,它们失败了

在您的示例中,/Admin/Index在技术上可以与HomeController匹配,因为它可以解释为/{area=Admin}/{action=Index}。似乎没有任何特殊的逻辑(或者至少不再有)来查看{action}段是否与同一区域中备用控制器上定义的RoutePrefix匹配


这似乎使这样的嵌套路由不再可能,因为您必须向HomeController添加定义的RoutePrefix(如“Home”)以区分控制器路由匹配。也许这可以通过RouteConstraint或其他机制解决,但我还没有找到解决方案

我认为您需要将每个控制器上的
[Route({action})]
更改为
[Route({action=Index})]

此外,您提到在
节控制器上有一个
索引
操作,但我在您的代码中没有看到它。我确实看到您有一个
部分
操作,上面列出了
[Route]
。我猜
部分
操作实际上是您在转到
/Admin/Sections
时想要得到的,在这种情况下,您应该删除
部分
操作上的
[Route]
,并将
部分控制器上的
[Route({action})]
更改为
[Route({action=Sections}]


希望有帮助

从5.0到5.1有一个突破性的变化,我打开了一个错误通知单,得到的响应是“按设计工作”。