Web API路由映射到root

时间:2012-11-16 17:31:50

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

我正在设置一个ASP.NET MVC 4 Web API来接受来自第三方服务器的请求,而我根本无法弄清楚如何设置路由映射。 假设第三方服务器希望获得以下响应:

  1. http://[my_server]/authorize?user=[user name]&session=[session token]&item=[item]
  2. http://[my_server]/release?user=[user name]&session=[session token]
  3. 或者,请求可以使用专用路径,即:

    1. http://[my_server]/***api***/authorize?user=[user name]&session=[session token]&item=[item]
    2. http://[my_server]/***api***/release?user=[user name]&session=[session token]
    3. 我希望能够支持这两种选择。

      应遵循更传统的/controller/id表单的其他请求也应该实现,但我想关注上述内容(我甚至不确定Web API是否通过去这里)。

      我写了以下控制器:

      public class MyController : ApiController
      {
          [HttpGet]
          [ActionName("authorize")]
          public string Authorize(string user, string session, string item)
          {
              ...
              // return "OK" or "DENY";
          }
      
          [HttpGet]
          [ActionName("release")]
          public string Release(string user, string session)
          {
              ...
              return "OK";
          }
      }
      

      并尝试了我在WebAppConfig.Register中的SO和其他地方找到的所有内容,但是当我在浏览器中尝试请求时,我一直收到404错误:

      http://localhost:22332/api/authorize?user=ury&session=token&item=an_item
      

      我的问题是,我需要做什么 - 特别是在WebAppConfig.Register和控制器中 - 为了满足上述要求(假设我的测试网址是正确的......)?

2 个答案:

答案 0 :(得分:2)

您将被Web API约定绊倒,以便将URL中的控制器名称与控制器类进行匹配。

如果您的控制器名称是“MyController”,则要请求的URL是:

http://localhost:22332/api/my/authorize?user=ury&session=token&item=an_item

要支持没有URL中“api”位的请求,只需在WebApiConfig.cs的Register方法中添加第二个路由定义。由于您还在URL中使用“操作”,因此您需要以下两条路线:

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Routes.MapHttpRoute(
        name: "RootWebApiRoute",
        routeTemplate: "{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

如果你想省略“api”前缀以及controller参数,我认为你需要一个不同的路由定义。类似的东西:

    public static void Register(HttpConfiguration config) {
        config.Routes.MapHttpRoute(
            name: "ActionOnlyRoute",
            routeTemplate: "{action}",
            defaults: new { controller = "My" }
        );
    }

在这里,我们只会在URL中查找“action”并将所有内容路由到“MyController”类。

答案 1 :(得分:1)

经过几个小时的工作并得到了Route Debugger的大量帮助 - 感谢Phil Haack! - 我发现了问题和解决方案。

问题:路线映射匹配是有序,而RouteTable.Routes从中初始化应用程序的路由映射,其中包含很多。我正在寻找的请求模式也与这些映射中的一些匹配(例如,“authorize”被匹配为控制器)。

解决方案:在默认映射之前添加“my”路由映射

是的,没错......

由于HttpRouteCollection不支持大多数操作,因此生成的代码有点难看,但它有效:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        routesCopy = new RouteBase[RouteTable.Routes.Count];

        RouteTable.Routes.CopyTo(routesCopy, 0);

        config.Routes.Clear();
        config.Routes.MapHttpRoute(name: "AuthorizeWebApiRoute", routeTemplate: "authorize", defaults: new { controller = "My", action = "authorize" });
        config.Routes.MapHttpRoute(name: "ReleaseWebApiRoute", routeTemplate: "release", defaults: new { controller = "My", action = "release" });

        foreach (var route in routesCopy)
        {
            RouteTable.Routes.Add(route);
        }
    }
}

只要“我的”路由映射与默认映射不匹配(我让它们具体到不足),我就会很好 - 我想......