我在我的 Controller 中使用来自 MVC5 的属性路由。
题:
有没有办法控制 Controller 之间的属性路由优先级?
考虑以下
[Route("home/{action=index}/{username?}")]
public class HomeController : Controller
{
[Route("home/index/{username?}", Order = 1)]
[Route("home/{username?}", Order = 2)]
[Route("{username?}", Order = 3)]
public ActionResult Index()
{
// ... bunch of stuff
}
}
基于上面的代码,
HomeController.Index()
应使用以下请求调用 action 方法:第二个 Controller :
[Authorize(Roles = "Member")]
[Route("profile/{action=index}")]
public class ProfileController : Controller
{
[Route("profile")]
public ActionResult Index()
{
}
}
ProfileController.Index()
应使用以下请求调用。问题
从示例中,如果我发送
domain/profile
在 url 中,抛出歧义异常。 domain/{username}
之间好像有歧义和 domain/profile
.现在,如果我使用基于约定的路由,这会起作用(第一场比赛获胜)。但是可以在MVC5属性路由中完成吗?因为我发现第三方库支持 Controller 之间的优先级
https://github.com/mccalltd/AttributeRouting/wiki/Controlling-Route-Precedence
routes.MapAttributeRoutes(config =>
{
config.AddRoutesFromController<ProfileController>();
config.AddRoutesFromController<HomeController>();
});
最佳答案
不,在 ASP.Net MVC 5.2.3 中不可能对 Controller 路由进行优先级排序。如果多个匹配,则忽略操作的顺序并抛出异常。
我已经通过从 https://aspnetwebstack.codeplex.com/SourceControl/latest 下载源代码验证了这一点。并检查函数 GetControllerTypeFromDirectRoute(如下)。从此函数发出的调用都没有对路由进行优先级排序,它们只是被发现并报告回来。如您所见,GetControllerTypeFromDirectRoute 只是引发了多个匹配。
一点都不好,但希望这会为其他人节省一些时间。
我放了一个手动映射的路线来避免这个问题。
private static Type GetControllerTypeFromDirectRoute(RouteData routeData)
{
Contract.Assert(routeData != null);
var matchingRouteDatas = routeData.GetDirectRouteMatches();
List<Type> controllerTypes = new List<Type>();
foreach (var directRouteData in matchingRouteDatas)
{
if (directRouteData != null)
{
Type controllerType = directRouteData.GetTargetControllerType();
if (controllerType == null)
{
// We don't expect this to happen, but it could happen if some code messes with the
// route data tokens and removes the key we're looking for.
throw new InvalidOperationException(MvcResources.DirectRoute_MissingControllerType);
}
if (!controllerTypes.Contains(controllerType))
{
controllerTypes.Add(controllerType);
}
}
}
// We only want to handle the case where all matched direct routes refer to the same controller.
// Handling the multiple-controllers case would put attribute routing down a totally different
// path than traditional routing.
if (controllerTypes.Count == 0)
{
return null;
}
else if (controllerTypes.Count == 1)
{
return controllerTypes[0];
}
else
{
throw CreateDirectRouteAmbiguousControllerException(controllerTypes);
}
}
关于asp.net-mvc-routing - MVC5 : Attribute Routing Precedence Among Controllers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21809556/