【问题标题】:MVC Routing not giving desired routeMVC 路由未提供所需路由
【发布时间】:2016-06-15 22:37:09
【问题描述】:

我的 RouteConfig.cs 文件中有以下代码:

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

    routes.MapRoute(
        name: "Location",
        url: "Order/Location",
        defaults: new { controller = "Order", action = "Location" }
    );

    routes.MapRoute(
        name: "Step3",
        url: "Order/{location}/{category}/{item}/{id}/{orderId}",
        defaults: new { controller = "Order", action = "Step3", orderId = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Step2",
        url: "Order/{location}/{category}/{orderId}",
        defaults: new { controller = "Order", action = "Step2", orderId = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Step1",
        url: "Order/{location}/{orderId}",
        defaults: new { controller = "Order", action = "Step1", orderId = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

这是我想要实现的目标:

-----------------------------------------------------------------------
| Url                                              | Desired Action   |
|--------------------------------------------------|------------------|
| http://localhost/Order/Phoenix                   | Step1            |
| http://localhost/Order/Phoenix/Parts             | Step2            |
| http://localhost/Order/Phoenix/Parts/Plugs/12    | Step3            |
| http://localhost/Order/Phoenix/47                | Step1            |
| http://localhost/Order/Phoenix/Parts/47          | Step2            |
| http://localhost/Order/Phoenix/Parts/Plugs/12/47 | Step3            |
|---------------------------------------------------------------------|

前 3 个 URL 正常工作,正如预期的那样。问题在于最后 3 个。我知道发生了什么。 MVC 路由引擎正在按照它们被映射的顺序评估路由,当它看到http://localhost/Phoenix/47 时,它认为47 是一个类别,并且在到达Step1 之前它会转到Step2。我几乎需要路由引擎足够聪明,才能知道一个数字是orderId

如何重新设计我的路线列表以获得所需的行为?

【问题讨论】:

  • {id}{orderId} 总是 int 吗?如果是这样,您也许可以使用路由约束(并且您的所有路由都以 Order/ 为前缀,但这未显示在您想要的结果中 - 这是一个错字吗?)
  • 是的,它们总是 int,是的,这是一个错字
  • 那么实际上是http://localhost/Order/Phoenix 等的网址,其中“Phoenix”是{location}
  • 是的。对此感到抱歉
  • 您应该编辑问题,使其清晰:)

标签: c# asp.net-mvc routes


【解决方案1】:

假设您在OrderController 中的方法是(特别是orderIdint 的类型)

// Order/{location}/{orderId}
public ActionResult Step1(string location, int? orderId)

// Order/{location}/{category}/{orderId}
public ActionResult Step2(string location, string category, int? orderId)

// Order/{location}/{category}/{item}/{id}/{orderId}
public ActionResult Step3(string location, string category, string item, int id, int? orderId)

您可以添加路由约束来检查是否提供了orderId 以及它是否是int。将路线的顺序更改为

routes.MapRoute(
    name: "Step1",
    url: "Order/{location}/{orderId}",
    defaults: new { controller = "Order", action = "Step1", orderId = UrlParameter.Optional },
    constraints: new { orderId = new OrderConstraint() }
);

routes.MapRoute(
    name: "Step2",
    url: "Order/{location}/{category}/{orderId}",
    defaults: new { controller = "Order", action = "Step2", orderId = UrlParameter.Optional },
    constraints: new { orderId = new OrderConstraint() }
);

routes.MapRoute(
    name: "Step3",
    url: "Order/{location}/{category}/{item}/{id}/{orderId}",
    defaults: new { controller = "Order", action = "Step3", orderId = UrlParameter.Optional },
    constraints: new { orderId = new OrderConstraint() }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

并添加路由约束

public class OrderConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        string v = values["orderId"].ToString();
        if (String.IsNullOrEmpty(v))
        {
            return true;
        }
        int value;
        return int.TryParse(values["orderId"].ToString(), out value);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 2023-03-24
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多