1

我在 ASP.NET MVC4 中创建了一个 rest API,并且遇到了路由问题。作为参考,我已经阅读了这些问题,但他们没有回答我的问题:

我要制作的网址如下:

  1. GET /account/id(其中 id 是一个 Guid) - 相当于 GET /account/?id=x
  2. GET /account/first%20last%20name(其中 name 是一个字符串) - 相当于 GET /account/?name=x
  3. GET /pendingregistrations/?page=y (此处省略动作)
  4. POST /pendingregistrations/denyregistration?denyId=x(这里指定了一个动作)

如您所见,在某些情况下,控制器名称后的 URL 映射到参数(上面 #1,2 中的 id 和名称),有时是操作名称(上面 #4)。此外,它可能根本不存在(上面的#3),在这种情况下,我假设一个默认操作。这是适用于几乎所有情况的路由:

    // Match for an id next.
    config.Routes.MapHttpRoute(
        name: "WithIdApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "Index" },
        constraints: new
        {
            id = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$"
        }
    );

    // Match for a name next.
    config.Routes.MapHttpRoute(
        name: "WithNameApi",
        routeTemplate: "api/{controller}/{name}",
        defaults: new { action = "Index" }
    );

    // Match for an action last.
    config.Routes.MapHttpRoute(
        name: "WithActionApi",
        routeTemplate: "api/{controller}/{action}",
        defaults: new { action = "Index" }
    );

此代码适用于除了上面的示例 #4 之外的所有内容,因为 MVC 无法区分 'name' 参数和 'action' 绑定之间的区别。如果我更改顺序(即,将匹配项放在上面),那么“名称”参数示例将永远无法工作。

有谁知道我可以做到这一点的任何方式?

4

1 回答 1

1

好吧,对于其他试图这样做的人来说,答案是不可能的。最好的办法是将“名称”搜索移动到它自己的操作中。例如:

  • GET /account/id(其中 id 是 Guid)
  • GET /account/name/first%20last

如果一个或另一个失败并且其他绑定可用,我会假设 MVC 会尝试匹配参数或操作,但遗憾的是事实并非如此。

于 2013-02-19T20:11:08.117 回答