我正在设置一个ASP.NET MVC 4 Web API来接受来自第三方服务器的请求,而我根本无法弄清楚如何设置路由映射。 假设第三方服务器希望获得以下响应:
http://[my_server]/authorize?user=[user name]&session=[session token]&item=[item]
http://[my_server]/release?user=[user name]&session=[session token]
或者,请求可以使用专用路径,即:
http://[my_server]/***api***/authorize?user=[user name]&session=[session token]&item=[item]
http://[my_server]/***api***/release?user=[user name]&session=[session token]
我希望能够支持这两种选择。
应遵循更传统的/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
和控制器中 - 为了满足上述要求(假设我的测试网址是正确的......)?
答案 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);
}
}
}
只要“我的”路由映射与默认映射不匹配(我让它们具体到不足),我就会很好 - 我想......