【问题标题】:ServiceStack: JsonServiceClient usage without IReturn in DTOServiceStack:DTO 中没有 IReturn 的 JsonServiceClient 使用
【发布时间】:2013-09-11 17:17:26
【问题描述】:

我想做的是:

var client = new JsonServiceClient(ServiceUrl);
var request = new FooQuery {Id = 1};
IEnumerable<Project> response = client.Get(request);

但是,我的 FooQuery 没有实现任何 IReturn,我不希望它实现(它在没有 ServiceStack 引用的库中)。这是我的服务端:

业务对象库:

public class ProjectQuery
{
    public int Id { get; set; }
}

应用主机:

Routes.Add<ProjectQuery>("/project", "GET");

服务:

public object Get(Foo request)
{
     // do stuff.
}

是否有一些不错的、干净的方法来创建 JsonServiceClient 而无需在我的业务对象上使用 IReturn 接口?

【问题讨论】:

  • 这篇文章 (stackoverflow.com/questions/12700702/servicestack-ireturn) 似乎与我想要的相似......但建议的方法对我不起作用(甚至无法编译)。
  • 我认为关键是找到一种方法将您的 Foo 对象转换为 URL 字符串,对吗?然后您可以围绕Get(string) 方法编写简单的包装器。在ServiceClientBase 类中的一些现有Get 方法中使用了ToUrl 扩展方法,但它们需要请求对象来实现IReturn(我看不出为什么IReturn 要求是在那里,如果它不在那里,那么我认为你的状态会很好)。
  • Mythz 在上一篇文章中说过,如果我们不在 DTO 上使用 IReturn 标记,那么我们可以使用 "List response = client.Get>(new ReqDto());"。我不认为他是正确的,因为 Get() 的 2 个重载要求 URL 或 IReturn。我的 DTO 可能非常复杂,所以我必须为每个 DTO 编写一个 URL 转换并让它们保持最新?这不是很好。

标签: c# servicestack


【解决方案1】:

如果您不想为 JsonServiceClient Get() 请求提供 URL,似乎没有办法不使用 IReturn。刚刚决定在我的 ServiceStack 实现中创建另一组 DTO,它们本质上是另一个库中真实 DTO 的镜像。然后当一个请求进入我的 SS DTO 时,我创建另一个库的 DTO,设置每个属性,然后传递它。

不漂亮,但这是迄今为止我能找到的最好的。

【讨论】:

  • 仅供参考,使用DTO's is recommended,您也可以使用内置的Auto Mapping 来减少样板/工作量。
  • 这真的很好 - 感谢您指出这一点。我现在正在重构以使用它,但下面 stefan2410 的答案更符合我所寻找的,用于分离业务对象和 SS。
【解决方案2】:

我在使用 IReturn 和 Routes 时遇到了同样的问题,因为我想使用 DTO
在具有业务逻辑的程序集中,没有 ServiceStack 引用。

它对我有用,在客户端模型中使用

   public class TestRequest
   {
        public int vendorId {get; set; }
        public string barcode {get; set; }     
        public string username { get; set; }   
        public string password { get; set; } 
   }    

然后在 AppHost 中

      Routes.Add<TestRequest( "/TestAPI/Reservation/{vendorId}/{barcode}"," GET,OPTIONS")   
            .Add<TestRequest>("/TestAPI/Reservation", "POST, OPTIONS")     

以及使用 POST 调用 JsonServiceClient

        request.vendorId=12344; 
        request.barcode="AAS1223"; 
        TestResponse response = client.Post<TestResponse>(server_ip + "/TestAPI/Reservation", request);  

或与 GET

   TestResponse response = client.Get<TestResponse>(server_ip + "/TestAPI/Reservation/12344/AAS1223?username=John&password=99");     

然后在服务Get或Post函数中

      public TestResponse Get(TestRequest request)
      {    
         // request members  hold  the values of the url.
         return  DoBusinessLayerWork(request);
      }

【讨论】:

  • 所以 Post 有一个接受请求对象的方法签名,但 Get 没有。但是我确实发现 Send() 确实允许发送请求对象...需要对 Send 和 Get/Post/etc 之间的区别进行更多研究...
  • 看起来 Get 和 Post 只是使用硬编码的 HttpMethod 调用 Send。好的,因此,如果您修改答案以使用发送而不是发布,那么任何情况下的任何人都可以接受。
  • 你没有像我问的那样包含 Send() 用法。在客户端中使用 Send() 是对我的问题的唯一有效答案(使用服务而不指定 URL,并且不使用 Post())。如果使用 Send(),则只需要 Http 方法(“GET”)、相对 URI 和请求对象。
  • 我使用 REST API。详细信息在这里ServiceStack C# client 其他人也许可以更好地解释 JsonServiceClient 中 Send() 的使用。但是 REST API 中的 Get 在 URL 中具有资源的值,例如,如果您使用 client.Send("GET",url,request),并且在 request.barcode 中您的值与 URL 不同路径,然后在服务 Get 函数中,请求将具有硬编码的值,而不是 URL 中的值,因为它是正确的。
  • 在客户端上使用 Send over Get 的要点是您不必使用 Send 指定 URL 查询参数。这就是为什么 Send 是可接受的答案,而不是 Get。
【解决方案3】:

使用 JsonServiceClient 类型中的 Send() 方法是执行此操作的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 2013-10-14
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多