我目前正在使用ASP.NET Web API设计REST API。
我想提供这样的方法(http方法无关紧要 - 应该适用于所有人):
问题是: ID 应该是可选的 - / api / client可能会返回客户列表 操作也应该是可选的 - 在一种情况下我想要获得特定客户端,而在另一种情况下,我想在该客户端上执行某个操作。 (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设计。
答案 0 :(得分:0)
如果您按如下方式定义路线:
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";
}
这应该可以应对你的网址组合
答案 1 :(得分:0)
不完全确定为什么你的第二种方法不起作用,但下面的路由配置对我有用
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 }
);
答案 2 :(得分:0)
这实际上是构建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:这是使用.net framework 4.5.2使用owin