我在MSDN上查看了this document,无法得出答案。
考虑到我的路线定义如下:
config.Routes.MapHttpRoute(
name: "DefaultWithActionAndID",
routeTemplate: "v{version}/{controller}/{action}/{id}",
defaults: null,
constraints: new {
action = @"[a-zA-Z]+",
id = @"\d+"
}
);
config.Routes.MapHttpRoute(
name: "DefaultWithID",
routeTemplate: "v{version}/{controller}/{id}",
defaults: null,
constraints: new {
id = @"\d+"
}
);
config.Routes.MapHttpRoute(
name: "DefaultWithoutActionOrId",
routeTemplate: "v{version}/{controller}",
defaults: null,
);
现在我有两个看起来像这样的控制器:
public class ItemController:ApiController{
[HttpGet]
public Item Get(int id){}
[HttpGet]
public Item GetSomething(int id){}
[HttpPut]
public Item Put(Item newItem){}
}
public class AnotherController:ApiController{
[HttpPut]
public HttpResponseMessage Put(Something item){}
}
我希望能够像这样调用所有这些端点:
GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334
PUT /api/Item body={newItem}
PUT /api/Another body={newSomething}
这将有效,但前提是我添加“Get”作为默认操作名称。如果我没有在我的路由中指定默认操作名称,那么它会抱怨多个匹配的操作名称。如果我确实添加了默认操作名称,那么我无法在没有错误的情况下调用PUT到Put()方法,因为操作名称与默认值不匹配且找不到。
// Will work in some cases, but not all
config.Routes.MapHttpRoute(
name: "DefaultWithID",
routeTemplate: "v{version}/{controller}/{id}",
defaults: new {
action="Get",
id=RouteParameters.Optional
},
constraints: new {
id = @"\d+"
}
);
// Works
GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334
// Doesn't work
PUT /api/Item body={newItem}
PUT /api/Another body={newSomething}
如何判断路由使用名称与我的HTTP谓词匹配的Action(如果存在,则在尝试使用之前)
答案 0 :(得分:3)
如果您按如下方式定义路线:
config.Routes.MapHttpRoute(
name: "DefaultWithActionAndID",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new {action = @"[a-zA-Z]+", id = @"\d*" }
);
config.Routes.MapHttpRoute(
name: "DefaultWithID",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "GET", id = RouteParameter.Optional },
constraints: new { id = @"\d*", httpMethod = new HttpMethodConstraint(new string[] { "GET" }) }
);
config.Routes.MapHttpRoute(
name: "DefaultWithoutActionOrId",
routeTemplate: "api/{controller}",
defaults: new { action = "PUT" },
constraints: new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) }
);
并将ActionName
属性放在GetSomething方法上:
[ActionName("Something")]
public Item GetSomething(int id){}
然后,您应该能够点击上面提到的所有端点。
答案 1 :(得分:0)
我看到它的方式你需要以下设置:
1
/api/Item/344
{controller}/{id}
2
/api/Item/Something/2334
{controller}/{action}/{id}
并按如下方式装饰'GetSomething'方法:
[ActionName("Something")]
public Item GetSomething(int id){}
3
/api/Item?id=344
/api/Item/Something?id=2334
我对这些并不完全确定 - 您是否尝试在上述路线中添加默认值:
defaults: new { id = RouteParameter.Optional }
4。
如果应用了#3,我希望PUT
能正常工作
如果有任何改变,请告诉我。