3

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

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

  • /api/客户端
  • /api/client/CID1234(CID1234 = ID)
  • /api/client/CID1234/orders(订单=操作)

问题是: 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,因为它无法区分“action”和“id”。“在与名称“CID1234”匹配的控制器“客户端”上未找到任何操作。

为了获得我需要的灵活性,我应该使用自定义 Actionselector 吗?或者是否有可能使用内置功能的 Web API?我了解有人可能希望将订单用作单独的实体。但我还不如在那里有真正的“行动”(而不是“实体”)。像“丢失密码”,“更改密码”等等。

感谢您的意见

PS:这里描述的事情并不是我愿意做的事情。糟糕的 api 设计。

4

3 回答 3

1

这实际上是构建 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 using owin

于 2015-03-30T20:53:02.137 回答
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";
}

这应该可以应对您的 url 组合

  • /休息/客户
  • /rest/client/CID1234
  • /rest/client/CID1234/orders
于 2013-03-27T11:39:48.160 回答
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 }
        );
于 2013-09-20T22:08:21.990 回答