具有MVC5属性路由的不明确路由

时间:2014-03-11 21:05:05

标签: c# asp.net-mvc-5 attributerouting

使用属性路由时,我遇到了模糊路由的问题。问题源于(我相信)在我们路线的根部使用变量参数。令我烦恼的是,文字参数似乎没有优先权,MVC5无法确定使用哪条路线。

我之前遇到过其他路线,并且认为我通过定义约定路线来管理修复。考虑到这一点,我在哪里可以找到有关属性路由的最佳实践的更多信息,并解决歧义?

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

  应用程序中的服务器错误。

     

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

     

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

     

的AccountController

     

RoundController

     

说明:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

     

异常详细信息:System.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)
    {
    }
}

2 个答案:

答案 0 :(得分:1)

我知道这不是你所要求的,但我认为这可以通过使用RoutePrefix属性来解决。 E.g。

[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"

但这只是猜测...

答案 1 :(得分:1)

我打算写一些比这更长的东西,但我还没有时间。我最终要解决的问题是删除对Microsoft的属性路由库的任何调用,而是使用&#34;属性路由&#34;包在这里找到。 http://htmlpreview.github.io/?https://github.com/mccalltd/AttributeRouting/blob/gh-pages/index.html

它一直运作良好,* Precedence属性解决了我在原始问题中遇到的确切问题。