我正在玩 ServiceStack 并尝试了解这项技术。
我有一个非常简单的设置(完整的解决方案是 available for download ):
Article
数据列表。 我为
ServiceStack.Pluging.MsgPack
安装了 nuget 包并添加了引用并正确设置了 AppHost 插件,如下面的 main()
代码所示。类 DTO 和服务
这些是我使用的数据类、DTO 和服务类:
public class Article : IReturn<Article>
{
public string AR_REF { get; set; }
public string AR_DESIGN { get; set; }
public string AR_CODEBARRE { get; set; }
public string FA_CODEFAMILLE { get; set; }
public string CT_INTITULE { get; set; }
}
public class Articles : IReturn<List<Article>> { }
public class ArticleService : Service
{
public List<Article> Get(Articles request) {
return new List<Article>() {
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
};
}
}
所有这些都是允许客户端获取 16 个虚拟
Articles
的列表。服务器和客户端请求
static void Main() {
var appHost = new AppHost();
appHost.Plugins.Add(new MsgPackFormat());
appHost.Init();
appHost.Start("http://localhost:8883");
// Fails when calling client.Get()
var client = new MsgPackServiceClient("http://localhost:8883");
List<Article> response = client.Get(new Articles());
appHost.Stop();
}
AppHost 定义为:
public class AppHost : AppHostHttpListenerBase
{
static readonly ConfigurationResourceManager AppSettings = new ConfigurationResourceManager();
public AppHost() : base("Test", typeof(Article).Assembly) { }
public override void Configure(Funq.Container container) { }
}
怎么了
client.Get(...)
调用失败,SerializationException
说:解包器还没有读取任何数据。解包器可能永远不会读取或底层流为空。
MsgPackServiceClient()
时会发生异常。奇怪的是,如果我返回 15 个或更少的
Articles
实例,它就可以工作。 JsvServiceClient()
或 JsonServiceClient()
,则返回数千条记录没有问题。 我真的不知道我是否做错了什么,或者这里是否有其他东西在起作用。
附加信息和下载
我将 VS2012 与通过 nuget 安装的 ServiceStack 3.9.43(包括 MsgPack 插件)一起使用。
无论编译选项如何 (AnyCPU/x86),都会出现问题。未启用代码优化(每个解决方案/项目选项都是默认选项)。
您可以 download the complete solution 并自己尝试。
最佳答案
所以,我不确定是什么问题。它似乎特定于在 AppHost 的同一应用程序中使用 MsgPackServiceClient。如果您从浏览器向 http://localhost:8883/Articles?format=x-msgpack
之类的内容发出请求,它似乎可以工作。
编写一个测试(如底部的一个)似乎确认 MessagePackSerializer 工作正常。
添加写入 OutputStream 的响应过滤器(如下)似乎可以解决您的问题。我尝试了列表中的 16 和 32 条记录。
希望这可以帮助。
appHost.ResponseFilters.Add((httpReq, httpRes, dto) =>
{
if (httpReq.ResponseContentType == ContentType.MsgPack)
{
using (var ms = new MemoryStream())
{
var serializer = MessagePackSerializer.Create(dto.GetType());
serializer.PackTo(Packer.Create(ms), dto);
var bytes = ms.ToArray();
var listenerResponse = (HttpListenerResponse)httpRes.OriginalResponse;
listenerResponse.OutputStream.Write(bytes, 0, bytes.Length);
httpRes.EndServiceStackRequest();
}
}
});
MessagePackSerializer 测试
[Test]
public void test()
{
var arts = new List<Article>() {
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
};
var serializer = MessagePackSerializer.Create<List<Article>>();
var ms = new MemoryStream();
serializer.PackTo(Packer.Create(ms), arts);
ms.Position = 0;
try
{
var obj = serializer.Unpack(ms);
Assert.IsNotNull(obj);
}
catch (Exception ex)
{
throw ex;
}
ms.Close();
}
关于c# - 获取数据时 ServiceStack MsgPackServiceClient 失败,但 JsonServiceClient 有效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16238889/