Mic*_*uso 93 asp.net routing action controller asp.net-web-api
我在Global.asax中有默认路由:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
我希望能够定位特定的功能,所以我创建了另一条路线:
RouteTable.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
所以,在我的控制器中,我有:
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
Run Code Online (Sandbox Code Playgroud)
打电话.../api/records/bycategoryid/5
会给我我想要的东西.但是,通话.../api/records/1
会给我错误
找到了与请求匹配的多个操作:...
我明白为什么那就是-航线只是定义哪些URL是有效的,但是当涉及到的功能匹配,都Get(int id)
和ByCategoryId(int id)
比赛api/{controller}/{id}
,这是混淆了框架.
我需要做些什么才能让默认的API路由再次运行,并保持一个{action}
?我想创建一个名为RecordByCategoryIdController
匹配默认API路由的不同控制器,我会请求它.../api/recordbycategoryid/5
.但是,我发现这是一个"脏"(因此不令人满意)的解决方案.我已经找到了这方面的答案,没有关于使用路线{action}
甚至提到这个问题的教程.
Chr*_* Li 102
路由引擎使用与向其中添加规则相同的顺序.一旦获得第一个匹配的规则,它将停止检查其他规则并采取此搜索控制器和操作.
所以,你应该:
将您的特定规则置于通用规则之前(如默认值),这意味着首先使用RouteTable.Routes.MapHttpRoute
"WithActionApi"映射,然后使用"DefaultApi".
删除defaults: new { id = System.Web.Http.RouteParameter.Optional }
"WithActionApi"规则的参数,因为一旦id是可选的,像"/ api/{part1}/{part2}"这样的url将永远不会进入"DefaultApi".
将命名操作添加到"DefaultApi"以告知路由引擎要输入的操作.否则,一旦您的控制器中有多个操作,引擎就不会知道要使用哪个操作,并抛出"找到了与请求匹配的多个操作:...".然后,为了使它与您的Get方法匹配,请使用ActionNameAttribute.
所以你的路线应该是这样的:
// Map this rule first
RouteTable.Routes.MapRoute(
"WithActionApi",
"api/{controller}/{action}/{id}"
);
RouteTable.Routes.MapRoute(
"DefaultApi",
"api/{controller}/{id}",
new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
而你的控制器:
[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
Run Code Online (Sandbox Code Playgroud)
MST*_*dev 38
您可以借助属性路由解决您的问题
调节器
[Route("api/category/{categoryId}")]
public IEnumerable<Order> GetCategoryId(int categoryId) { ... }
Run Code Online (Sandbox Code Playgroud)
jquery中的URI
api/category/1
Run Code Online (Sandbox Code Playgroud)
路线配置
using System.Web.Http;
namespace WebApplication
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且您的默认路由作为默认的基于约定的路由
调节器
public string Get(int id)
{
return "object of id id";
}
Run Code Online (Sandbox Code Playgroud)
Jquery中的URI
/api/records/1
Run Code Online (Sandbox Code Playgroud)
路线配置
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Run Code Online (Sandbox Code Playgroud)
查看文章了解更多信息属性路由和基于诊断的路由在这里和此