servicestack,Web Services,Rest,Routes,servicestack" /> servicestack,Web Services,Rest,Routes,servicestack" />

Web services ServiceStack客户端和不明确路由

Web services ServiceStack客户端和不明确路由,web-services,rest,routes,servicestack,Web Services,Rest,Routes,servicestack,我有一个服务堆栈服务,我们将调用Orders,它具有标准的GET路由 /orders-获取所有客户 /orders/{Ids}-获取特定客户 这一切都很好,但我想我应该添加另一条路线 /orders/customers/{CustomerId}-获取具有特定客户id的订单 当在浏览器中点击路由时可以找到,但当我使用ServiceStack客户端时,会出现不明确路由异常,它列出了三条路由 我不太确定最好的解决方法是什么……我所做的不是正确的RESTish方式吗 我知道我只需手动将路由输入J

我有一个服务堆栈服务,我们将调用
Orders
,它具有标准的GET路由

  • /orders
    -获取所有客户
  • /orders/{Ids}
    -获取特定客户
这一切都很好,但我想我应该添加另一条路线

  • /orders/customers/{CustomerId}
    -获取具有特定客户id的订单
当在浏览器中点击路由时可以找到,但当我使用ServiceStack客户端时,会出现不明确路由异常,它列出了三条路由

我不太确定最好的解决方法是什么……我所做的不是正确的RESTish方式吗

我知道我只需手动将路由输入
JsonServiceClient
即可

client.Get(“/orders/customers/7”)

这也行,但我更喜欢用打字的方式…也就是说

client.Get(新订单请求{CustomerId=7})

下面是我正在使用的RequestDTO示例

public class OrdersRequest : IReturn<List<Orders>>
{
   public int[] Ids {get; set;}
   public CustomerId {get; set;}

   public OrdersRequest(params int[] ids)
   {
        this.Ids = ids;
   }
}
公共类订单请求:IReturn
{
公共int[]Ids{get;set;}
公共CustomerId{get;set;}
公共订单请求(参数int[]id)
{
这个.Ids=Ids;
}
}
我必须使用不同的DTO进行此操作还是

如果有任何帮助或指向任何示例的指针能够解决这个问题,或者有更好的方法来创建服务,我们将不胜感激


谢谢

我的建议是你没有正确使用REST。有。刚开始的时候这是一个常见的问题,我也有类似的问题

了解您的用例: 在您的具体案例中,如果我们看一下
/orders/customers/7
,如果您这样想,效果会更好:

/客户/7/订单

您这样做的原因是:

  • 它解决了路线模糊的问题
  • 背景很清楚。我们可以看到,我们正在使用Customer 7,而无需导航长url
  • 我们可以看到“与客户7”我们想要他们的订单
可以这样想:

/orders                   Everybody's Orders
/orders/1                 Order 1 (without being aware of the customer it belongs to)
/customers                All Customers
/customers/7              Customer 7's details
/customers/7/orders       All Customer 7's orders
/customers/7/orders/3     Customer 7's order number 3
这样做的好处在于数据操作的一致性。因此,您希望查找所有已取消的订单:

/orders/cancelled
您想通过其
orderId

/orders/4/cancel
您要列出特定客户的未结订单

/customers/6/orders/open
您想列出客户6已取消的订单

/customers/6/orders/cancelled
您想取消正在查看的客户6的订单

/customers/6/orders/2/cancel
显然,这些只是场景,你的路线会有所不同

简化操作处理程序: 您可能需要定义动作处理程序,以便它们能够处理来自多个路由的动作。我的意思是,一个操作处理程序将负责列出订单

/orders
/customers/6/orders
我所做的是:

[路由(“/orders”,“GET”)]
[路线(“/customers/{CustomerId}/orders”,“GET”)]
公共类ListOrdersRequest:IReturn
{
public int?CustomerId{get;set;}
}
因此,您可以看到两个订单列表路线。如果他们使用
/orders
,则我们的
customerId
将没有值,但另一条路径将有值。因此,在我们的操作处理程序中,我们可以简单地测试:

公共列表获取(ListOrdersRequest请求)
{
//使用“CustomerId”缩小搜索范围
if(request.CustomerId.HasValue){
//查找特定于客户的订单
}否则{
//查找所有订单
}
退货订单;
}
客户端关注点: 因此,要解决您使用“类型化”客户端的问题。使用上述方法创建路由和操作处理程序将允许您执行以下操作:

client.Get(新的ListOrdersRequest{CustomerId=7});//获取客户7的订单
client.Get(新建ListOrdersRequest());//所有命令
因此,为您提供了一个列出订单的清晰方法

最后的想法: 显然,这意味着你将不得不重做你所拥有的,这可能是一种痛苦,但这是最好的方法,值得付出努力

我希望这有助于您理解最佳结构


更新: @stefan2410要求我解决Kyle在GET请求的路由中使用
int[]
的问题:

如果您想在GET请求中使用<代码> INT[]/COD>,您必须考虑在URL中的传输过程中更改它,以便可以放心使用。

所以你可以这样做:

类顺序请求
{
公共字符串ID{get;set;}
公共订单请求(int[]id)
{
Ids=string.Join(“,”,Array.ConvertAll(ints,item=>item.ToString());
}
}
Get(newordersrequest(new[]{1,2,3}));
创建路由
/orders/1,2,3
并匹配
/orders/{Ids}
。这样做的问题是,为了在服务器端使用ID,您必须将字符串
“1,2,3”
转换回
int[]

处理请求中的
int[]
的更好方法是使用POST。因此,您可以:

类顺序请求
{
公共int[]Ids{get;set;}
公共订单请求(int[]id)
{
Ids=Ids;
}
}    
client.Post(newordersrequest(new[]{1,2,3}));

创建路线
/orders
并匹配路线
/orders

非常有用的答案,如果可以的话,我会给你+2。@Scott,也许你说的路线更符合用例,但我不明白歧义在哪里。Dto(带参数数组的构造函数)中有错误。还有/orders/{Ids},首先它意味着订单的ID而不是客户的ID,其次,Get中是否可能在Uri中有一个整数数组?(当然不是正确的REST)@stefan2410是的,你是对的,在路由中传递一个ID数组是错误的。我认为Kyle可能简化了他的问题,消除了歧义,但他确实在访问请求(可能是其他路由)时通过一个
含糊不清的routeException
说出了这个问题。使用
/orders/customers
lea