我正在创建以下控制器:
public FoosController : ApiController
{
public IQueryable Get()
{
return AnODataQueryableListOfFoos();
}
public void Delete(Guid id)
{
DeleteTheFooWithId(id);
}
public IQueryable<Bar> GetBars(Guid id)
{
var foo = GetFooById(id);
return AnODataQueryableListOfBarsForThisFoo(foo);
}
public IEnumerable ProjectedBars(Guid id)
{
var foo = GetFooById(id);
return foo.Qux
? OneProjectionOfBars(foo)
: AnotherProjectionOfBars(foo);
}
}
(酒吧列表可以被认为是Foo的“内容”......)
我打算使用以下网址:
GET /api/Foos -> Get
GET /api/Foos/SOME_GUID/Bars -> GetBars
GET /api/Foos/SOME_GUID/ProjectedBars -> GetProjectedBars
DELETE /api/Foos/SOME_GUID -> Delete
我尝试了[ActionName]
和自定义路线的几种组合,但始终存在冲突或404。
最简单的方法是什么?如果可能的话,我想保持我的路线通用(即没有特定于控制器的东西)。其他控制器使用更标准的/Stuff
- Stuff/id
方法。
我也向那些指出我完全滥用网址的人开放。欢迎改进。
答案 0 :(得分:2)
我同意属性路由是最好的方法,但您可以尝试以下方法:
public FoosController : ApiController
{
[HttpGet]
public IQueryable Get()
{
return AnODataQueryableListOfFoos();
}
[HttpGet]
[ActionName("Bars")]
public IQueryable<Bar> GetBars(Guid id)
{
var foo = GetFooById(id);
return AnODataQueryableListOfBarsForThisFoo(foo);
}
[HttpGet]
[ActionName("ProjectedBars")]
public IEnumerable GetProjectedBars(Guid id)
{
var foo = GetFooById(id);
return foo.Qux
? OneProjectionOfBars(foo)
: AnotherProjectionOfBars(foo);
}
}
然后使用以下路线:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{id}/{action}"
);
答案 1 :(得分:0)
您要求的是n深度子资源,唯一真正的解决方案是Web API的v2中提供的属性路由。在它发布之前(我相信很快就会发布),你可以使用类似RPC的方法:
routes.MapHttpRoute("RPC", "rpc/{controller}/{id}/{action}");
您需要将此注册为第一个HTTP路由,并使用“api”以外的前缀,以便它不会与实际的api / routes冲突。