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

C# 具有MVC5属性路由的不明确路由,c#,asp.net-mvc-5,attributerouting,C#,Asp.net Mvc 5,Attributerouting,使用属性路由时,我遇到了不明确路由的问题。问题源于(我相信)在我们路线的根本上使用可变参数。让我烦恼的是,文字参数似乎没有优先权,MVC5无法确定使用哪条路由 我以前在使用其他路由时遇到过这种情况,并认为我已经通过定义约定路由解决了这个问题。考虑到这一点,我在哪里可以找到关于属性路由和解决歧义的最佳实践的更多信息 这是我遇到问题的代码,以及异常 “/”应用程序中出现服务器错误 找到多个与URL匹配的控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则可能发生这种情况 请求已找到以下匹配的

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

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

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

“/”应用程序中出现服务器错误

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

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

会计控制员

圆形控制器

说明:执行当前web请求期间发生未经处理的异常。请查看堆栈跟踪以了解有关错误的更多信息以及错误在代码中的起源

异常详细信息:System.InvalidOperationException:找到多个与URL匹配的控制器类型。如果多个控制器上的属性路由与请求的URL匹配,则可能发生这种情况

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

会计控制员

圆形控制器

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)
    {
    }
}
public class AccountController : ControllerBase
{
    [AllowAnonymous]
    [Route("Account/ResetPassword/{token}")]
    public async Task<ActionResult> ResetPassword(string token)
    {
    }
}
公共类RoundController:ControllerBase
{
[路由(“{groupid}/{campaignid}/{accesstoken}”)]
公共异步任务TempRoundLink(字符串groupid、字符串活动ID、字符串accesstoken)
{
}
}
AccountController.cs

public class RoundController : ControllerBase
{
    [Route("{groupid}/{campaignid}/{accesstoken}")]
    public async Task<ActionResult> TempRoundLink(string groupid, string campaignid, string accesstoken)
    {
    }
}
public class AccountController : ControllerBase
{
    [AllowAnonymous]
    [Route("Account/ResetPassword/{token}")]
    public async Task<ActionResult> ResetPassword(string token)
    {
    }
}
公共类AccountController:ControllerBase
{
[异名]
[路由(“帐户/ResetPassword/{token}”)]
公共异步任务重置密码(字符串令牌)
{
}
}

我知道这不是您想要的,但我认为可以通过使用
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)
    {
    }
}

但那只是一个猜测…

我本打算写一些比这长得多的东西,但我没有时间。我最终采用的解决方案是去掉对Microsoft的属性路由库的任何调用,而是使用此处找到的“属性路由”包


它一直运行得很好,*优先级属性解决了我在原始问题中遇到的问题。

我想,
RoutePrefix
是我的答案。不幸的是,RoundController操作都以一个可变参数开始,而不是“Round”。我认为在使用相同方法的
RoutePrefix
时,在AccountController操作中保留“Account”,这意味着请求URL必须是“/Account/Account/ResetPassword/abc123”我希望使用
RoutePrefix
priority
参数,但它似乎不再受支持。我的想法是,假设文字应该首先从左边匹配。我确信它不这样做是有原因的,但我不知道为什么。您的示例将匹配Account/ResetPassword/{token},因为Account匹配文本,ResetPassword匹配第二个文本。此时,文字“alpha”无法匹配。如果您需要保持与现有路由的向后兼容性,那么是的,这会使它更加困难。我不久前发现了一个或两个NuGet软件包,它安装了一些功能,允许跟踪解析如何发生,以帮助解决路由错误。不过我不记得那些人的名字了。你可以试试这些,看看它们是否能让你洞察为什么它与你的期望相匹配。也许这将有助于找到另一种方法或确定如何正确注册路线。谢谢!看起来像是2008年发布的。我要试一试@阿霍姆斯是的,那是他们中的一个,这是我最幸运的一个。它确实有一个警告,出于某种原因,它不适用于扩展名为.xml(或其他)的请求,但适用于.json或任何其他任意扩展名(项目被设置为完全忽略扩展名)。所以请记住,如果它给出了奇怪的行为,以奇怪的方式修改请求实际上可能会使它工作(最优秀的黑色艺术)。有同样的麻烦。我可以通过添加一个否定的正则表达式约束来解决这个问题,但我认为这是不对的。它很快就会失控,很难维护。嗨@JoshWheelock,我需要道歉-我打算写下我找到的解决方案。我也有一个开始的限制,但放弃了一些更易于维护的东西。最后,我剥离了我们使用的所有Microsoft属性路由,并使用了“属性路由”,这是一个完全不同的包。这是一种享受@aholmes的url已失效,当前的url已失效。感谢您更新链接!更新@chris marisic用上面更新的URL发表了评论。我不敢相信我必须在这上面转储MS路由,但这是我找到的唯一解决方案。有人找到了真正的解决方案吗?已经有几年了,但如果我正确地回忆起我在研究中发现的,那就是Microsoft库不适用于这些更复杂的情况,因此我认为MS路由解决方案是不可能的。它过去没有抛出异常。根据我定义的路线的文字部分,我认为它做了正确的事情。现在看来它从来没有这样做过,我只是对它选择的路线感到幸运。现在我的一堆应用程序都抛出了异常。