我目前正在使用ASP.NET Web API设计REST API。
我想提供这样的方法(http方法无关紧要 - 应该适用于所有人):
问题是:Id应该是可选的 - / api / client可以返回客户列表Action也应该是可选的 - 在一种情况下我想获得一个特定的客户端而在另一种情况下我想在该客户端上执行某个操作。 (RPC风格)
我不认为我可以使用约束,因为我使用的“ID”看起来非常不同。
这种方法不起作用:
config.Routes.MapHttpRoute(
name: "RpcStyleApi",
routeTemplate: "rest/{controller}/{action}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional }
);
这种方法既不起作用:
config.Routes.MapHttpRoute(
name: "RpcStyleApi",
routeTemplate: "rest/{controller}/{action}"
);
config.Routes.MapHttpRoute(
name: "RpcStyleApi2",
routeTemplate: "rest/{controller}/{id}/{action}",
defaults: new { action = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "rest/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
例如,它返回404,因为它无法区分“动作”和“id”。 “在名称为'CID1234'的控制器'客户'上找不到任何操作。
为了获得我需要的灵活性,我应该选择自定义Actionselector吗?或者是否可以使用内置的Web API功能?我知道有人可能希望将订单用作单独的实体。但我可能还有真正的“行动”(而不是“实体”)。像“lostpassword”,“changepassword”等等。
感谢您的意见
P.S。:像here描述的东西并不是我愿意做的事情。糟糕的api设计。
这实际上是构建restful API时的最佳实践之一,这里是关于构建API https://www.youtube.com/watch?v=ZpqCN8iO9Y8时要考虑的不同方面的一个小视频
解决方案:您不需要更改映射路由,您需要的所有内容都使用每个方法之上的方法属性,如下所示
\\ api/clients [this should be clients not client if its returning a list]
[Route("api/clients")]
public IHttpActionResult Get()
{
return Ok("here you list of clients");
}
/api/client/CID1234 (CID1234 = Id)
[Route("api/clients/{Id}")]
public IHttpActionResult Get(string Id)
{
return Ok("use the Id to retrieve the client details");
}
/api/client/CID1234/orders (orders = action)
[Route("api/clients/{Id}/orders")]
public IHttpActionResult GetOrders(string Id)
{
return Ok("use the Id to retrieve the client orders");
}
关于可选项,现在您可以在获取其值时在方法内部构建自己的逻辑。
本文有关于这一点的更多细节
https://aspnetwebstack.codeplex.com/wikipage?title=Attribute%20Routing%20in%20MVC%20and%20Web%20API
PS:这是使用owin的.Net framework 4.5.2
如果您按如下方式定义路线:
config.Routes.MapHttpRoute(
name: "RpcStyleApi1",
routeTemplate: "rest/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Get" }
);
config.Routes.MapHttpRoute(
name: "RpcStyleApi2",
routeTemplate: "rest/{controller}/{id}/{action}"
);
然后,您可以在控制器上创建方法,如下所示:
public string Get()
{
return "GET";
}
public string Get(string id)
{
return "GETID";
}
public string Orders(string id)
{
return "GETORDERS";
}
这应该应对你的网址组合
不确定为什么你的第二种方法不起作用,但下面的路由配置对我有用
config.Routes.MapHttpRoute(
name: "WebApiWithActionRouteName"
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "WebApiDefaultRouteName",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);