asp.net web api路由设计(多条路由)

时间:2013-02-06 08:04:57

标签: asp.net-web-api asp.net-routing asp.net-web-api-routing

我目前正在使用ASP.NET Web API设计REST API。

我想提供这样的方法(http方法无关紧要 - 应该适用于所有人):

  • / API /客户端
  • / api / client / CID1234(CID1234 = Id)
  • / api / client / CID1234 / orders(orders = action)

问题是: 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设计。

3 个答案:

答案 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";
}

这应该可以应对你的网址组合

  • /休息/客户端
  • /休息/客户端/ CID1234
  • /休息/客户端/ CID1234 /订单

答案 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