带有MVC5属性路由的模糊路由

本文关键字:路由 模糊 属性 MVC5 带有 | 更新日期: 2023-09-27 17:49:30

我在使用属性路由时遇到了歧义路由的问题。问题源于(我相信)在我们的路由中使用可变参数。令我烦恼的是,文字参数似乎没有优先级,MVC5无法确定使用哪条路由。

我以前在使用其他路由时遇到过这个问题,并认为通过定义约定路由已经解决了这个问题。考虑到这一点,我在哪里可以找到有关属性路由和解决歧义的最佳实践的更多信息?

这是我遇到问题的代码,以及异常。

'/'应用程序出现服务器错误。

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

请求已找到以下匹配的控制器类型:

AccountController

RoundController

Description:当前web请求执行过程中发生未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源位置的更多信息。

Exception Details: System. sh InvalidOperationException:找到了多个匹配URL的控制器类型。如果多个控制器上的属性路由与请求的URL匹配,就会发生这种情况。

请求已找到以下匹配的控制器类型:

AccountController

RoundController

RouteConfig.cs

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    // I added this constraint resolver to resolve some other ambiguous routes that end
    // with a literal, but MVC5 wasn't able to determine whether to use those routes
    var constraintResolver = new System.Web.Mvc.Routing.DefaultInlineConstraintResolver();
    constraintResolver.ConstraintMap.Add("notWriteAction", typeof(IsNotWriteActionConstraint));
    routes.MapMvcAttributeRoutes(constraintResolver);
    // This is the convention route I added to resolve another ambiguous route.
    routes.MapRoute(
        name: "Account",
        url: "Account/{action}/{GroupName}/{AccessToken}",
        defaults: new { controller = "Account", action = "Login", GroupName = UrlParameter.Optional, AccessToken = UrlParameter.Optional }
    );
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

RoundController.cs

public class RoundController : ControllerBase
{
    [Route("{groupid}/{campaignid}/{accesstoken}")]
    public async Task<ActionResult> TempRoundLink(string groupid, string campaignid, string accesstoken)
    {
    }
}

AccountController.cs

public class AccountController : ControllerBase
{
    [AllowAnonymous]
    [Route("Account/ResetPassword/{token}")]
    public async Task<ActionResult> ResetPassword(string token)
    {
    }
}

带有MVC5属性路由的模糊路由

我知道这不是你想要的,但我认为这可以通过使用RoutePrefix属性来解决。例如

[RoutePrefix("Round")]
public class RoundController : ControllerBase
{
    [Route("{groupid}/{campaignid}/{accesstoken}")]
    public async Task<ActionResult> TempRoundLink(string groupid, string campaignid, string accesstoken)
    {
    }
}
[RoutePrefix("Account")]
public class AccountController : ControllerBase
{
    [AllowAnonymous]
    [Route("Account/ResetPassword/{token}")]
    public async Task<ActionResult> ResetPassword(string token)
    {
    }
}

我认为它试图不做假设的原因是因为偏好可能并不总是可以确定的。例如,你希望路由器如何找出这两个:

Routes (from attributes):
"Account/ResetPassword/{token}"
"Account/{something}/alpha"
Reequest:
"/Account/ResetPassword/alpha"

我想写一些比这更长的东西,但是我没有时间。我最终采用的解决方案是去掉对微软属性路由库的任何调用,而是使用这里找到的"属性路由"包。http://htmlpreview.github.io/?https://github.com/mccalltd/AttributeRouting/blob/gh-pages/index.html

它一直工作得很好,并且*Precedence属性解决了我在原始问题中遇到的确切问题。