0

尽管我在直接 MVC 中使用了路由,但我并没有过多地使用 ASP.NET WebAPI。显然我做错了什么,也许有人可以帮忙?我有一个名为 UsersController 的控制器和两个方法,Register 和 Details,它们都接受两个字符串参数并返回一个字符串,都标记为 HttpGet。最初我从 WebApiConfig.cs 中的两个路由映射开始:

config.Routes.MapHttpRoute(
      name: "TestApi",
      routeTemplate: "api/{controller}/{action}/{userId}/{key}"
  );
  config.Routes.MapHttpRoute(
      name: "Test2Api",
      routeTemplate: "api/{controller}/{action}/{userId}/{class}"
  );

通过此设置,只能找到 URL 的第一个路由,例如:

http://<domain>/api/users/register/a123/b456/

如果我打电话:

http://<domain>/api/users/details/a123/b456/

我得到一个 404。如果我交换两条路由,那么我可以调用 Details 方法但不能调用 Register 方法,再次得到 404。我采用的解决方法是更具体地使用路由:

config.Routes.MapHttpRoute(
      name: "TestApi",
      routeTemplate: "api/{controller}/register/{userId}/{key}"
  );
  config.Routes.MapHttpRoute(
      name: "Test2Api",
      routeTemplate: "api/{controller}/details/{userId}/{class}/"
  );

用户控制器看起来像:

namespace HelloWebAPI.Controllers
{
  using System;
  using System.Web.Http;
  using HelloWebAPI.Models;

    public class UsersController : ApiController
    {
      [HttpGet]
      public string Register(string userId, string key)
      {
        return userId + "-" + key;
      }

      [HttpGet]
      public string Enrolments(string userId, string @class)
      {
        return userId + "-" + @class
      }
    }
}

所以我不明白为什么第二个注册的路由的 {action} 组件没有与正确的方法相关联。

谢谢

4

2 回答 2

2

ASP.NET Web API 中的路由分三个步骤工作:

  1. 将 URI 与路由模板匹配。
  2. 选择控制器。
  3. 选择一个动作。

框架在路由表中选择与 URI 匹配的第一个路由,如果第二步或第三步失败,则没有“第二次猜测” - 只有 404。在您的情况下,两个 URI 始终与第一个路由匹配,因此第二个永远不会用过的。

为了进一步分析,我们假设第一条路线是:

api/{controller}/{action}/{userId}/{key}

您使用以下 URI 调用它:

http://<domain>/api/users/enrolments/a123/b456/

为了选择动作框架,需要检查三件事:

  • 请求的 HTTP 方法。
  • 路由模板中的{action}占位符(如果存在)。
  • 控制器上的动作参数。

在这种情况下,该{action}部分将被正确解析为enrolments,但框架将寻找Enrolments带有userIdkey参数的方法。您的方法有一个class不匹配的参数。这将导致 404。

为了避免这个问题,您必须制定更具体的路线(就像您所做的那样)或统一参数名称。

于 2013-03-22T09:25:02.513 回答
1

您只需要定义一个路由:

config.Routes.MapHttpRoute(
    name: "TestApi",
    routeTemplate: "api/{controller}/{action}/{userId}/{key}"
);

然后将您的控制器方法更改为以下内容:

[HttpGet]
public string Register(string userId, string key)
{
  return userId + "-" + key;
}

[HttpGet]
public string Details(string userId, string key)
{
  return userId + "-" + key
}
于 2013-03-22T09:21:23.370 回答