在MVC 4 WebAPI中无法识别路由

时间:2013-03-21 16:59:20

标签: asp.net asp.net-web-api asp.net-web-api-routing

虽然我在直接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}/"
  );

UsersController看起来像:

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}组件没有与正确的方法相关联。

由于

2 个答案:

答案 0 :(得分:2)

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

  1. 将URI与路径模板匹配。
  2. 选择控制器。
  3. 选择一项行动。
  4. 框架选择路由表中与URI匹配的第一个路由,如果第二或第三步失败,则没有“第二次猜测” - 只有404.在您的情况下,两个URI始终与第一个路由匹配,因此第二个从未使用过。

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

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

    您可以使用以下URI调用它:

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

    为了选择行动框架,正在检查三件事:

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

    在这种情况下,{action}部分将正确解析为enrolments,但框架将使用EnrolmentsuserId参数查找key方法。您的方法具有class参数,该参数不匹配。这将导致404。

    要避免此问题,您必须制作更具体的路线(就像您一样)或统一参数名称。

答案 1 :(得分: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
}