两条不同路由上的MVC路由属性错误

时间:2014-11-07 17:07:24

标签: asp.net-mvc attributerouting

我在MVC 5.2中遇到属性路由错误。错误是

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

有问题的路线是

[Route("{classname}/{id:int}")]
[Route("Edit/{id:int}")]

url / Edit / 123抛出错误,而url / someword / 123 不会抛出错误

鉴于Edit / 123比someword / 123更具体,为什么会在/ Edit / 123上抛出错误?

谢谢,

约翰

2 个答案:

答案 0 :(得分:3)

路由框架不会判断你可能想要的路线(实际上有一条带有Edit的路线,显然我想要那条路线)。它所看到的只是它有两条与它所拥有的URL相匹配的路线,并且它会举手。

以下内容应该可以解决歧义,只要您永远不需要“编辑”作为classname的值:

[Route("{classname:regex(^(?!Edit)$)}/{id:int}")]

答案 1 :(得分:0)

有两种方法可以解决这个问题:

克里斯指出正则表达式约束。

或自定义路线约束,例如:https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/

您可以通过实现IRouteConstraint接口来创建自定义路由约束。例如,以下约束将参数限制为有效值集:

public class ValuesConstraint : IRouteConstraint
{
    private readonly string[] validOptions;
    public ValuesConstraint(string options)
    {
        validOptions = options.Split('|');
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object value;
        if (values.TryGetValue(parameterName, out value) && value != null)
        {
            return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase);
        }
        return false;
    }
}

以下代码显示了如何注册约束:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        var constraintsResolver = new DefaultInlineConstraintResolver();

        constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint));

        routes.MapMvcAttributeRoutes(constraintsResolver);
    }
}

现在您可以在路线中应用约束:

public class TemperatureController : Controller
{
    // eg: temp/celsius and /temp/fahrenheit but not /temp/kelvin
    [Route("temp/{scale:values(celsius|fahrenheit)}")]
    public ActionResult Show(string scale)
    {
        return Content("scale is " + scale);
    }
}

在我看来,这不是一个很好的设计。除非您自己明确设置,否则没有关于您想要的URL的判断以及匹配时没有特异性规则。但至少你可以按照自己想要的方式获取网址。希望您的约束列表不会太长。如果是,或者您不想对路由字符串参数及其约束进行硬编码,则可以在操作方法之外以编程方式构建它,并将其作为变量提供给Route属性。