使用 Protobuf 格式的 ServiceStack

Posted

技术标签:

【中文标题】使用 Protobuf 格式的 ServiceStack【英文标题】:ServiceStack with Protobuf format 【发布时间】:2013-03-28 09:21:54 【问题描述】:

我正在尝试在 ServiceStack Webservices 中使用 protobuf 格式(按照ServiceStack: REST with ProtoBuf by Steven Hollidge 的示例。我添加了一个 Winform 应用程序来使用 Web 服务。代码如下。

HelloService.cs

using System.Runtime.Serialization;
using ProtoBuf;
using ServiceStack.Demo.Rest;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;

namespace ServiceStack.Demo.WebService

[DataContract] 
public class Hello

    [DataMember(Order = 1)]
    public string Name  get; set; 

 [DataContract] 
public class HelloResponse

    [DataMember(Order = 1)]
    public string Result  get; set; 


 public class HelloService : RestServiceBase<Hello>

    public  override object OnGet(Hello request)
    
        return new HelloResponse  Result = "Hello, " + request.Name ;
    


Global.asax.cs

using System;
using System.Web;
using Funq;
using ServiceStack.Demo.Rest;
using ServiceStack.Demo.WebService;
using ServiceStack.WebHost.Endpoints;

namespace ServiceStack.Demo

public class AppHost : AppHostBase

    public AppHost() : base("ServiceStack makes services easy!", typeof (AppHost).Assembly)
    
        ServiceStack.Plugins.ProtoBuf.AppStart.Start();
    

    public override void Configure(Container container)
    
        Routes
          .Add<Hello>("/hello")
          .Add<Hello>("/hello/Name");

    
 

public class Global : HttpApplication

    protected void Application_Start(object sender, EventArgs e)
    
        new AppHost().Init();
    


Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ServiceStack.ServiceClient;
using ProtoBuf;
using ServiceStack.Plugins.ProtoBuf;
using System.Runtime.Serialization;
using ServiceStack.ServiceClient.Web;

namespace client

public partial class Form1 : Form

    private ServiceClientBase _client;
    private const string Url = "http://localhost/servicestack.demo/servicestack/hello?format=x-protobuf";
    public Form1()
    
        InitializeComponent();
    

    private void Button1Click(object sender, EventArgs e)
    

        this._client =
            new ProtoBufServiceClient(Url);

        var response = _client.Send<HelloResponse>(new Hello Name = "ProtoBuf");
        label1.Text = response.Result;
    

   
    public class Hello
    
        public string Name  get; set; 
    

    
    public class HelloResponse
    
        public string Result  get; set; 
    


我收到System.InvalidOperationException: Type is not expected, and no contract can be inferred: client.Form1+Hello

我做错了什么?请推荐.....

【问题讨论】:

只是为了确保它与类的嵌套命名无关,移动类型 Hello 使其不嵌套在 Form1 类中。 是这样吗,类型不是预期的,也无法推断出合约:client.Hello 发生在 var response = _client.Send(new Hello Name = "ProtoBuf"); 【参考方案1】:

看起来你有你的Hello 类和你的HelloResponse 类声明了两次。一次在 HelloService.cs 中,再次作为 Form.cs 中的内部类。从 Form.cs 文件中删除重复项应该允许您的 ProtoBufServiceClient 引用正确的类/类型。

【讨论】:

【参考方案2】:

我已将 Form1.cs 更新为以下内容,现在可以正常工作(请参阅http://upjnv.blogspot.in/

 using System;  
 using System.Windows.Forms;  
 using ServiceStack.Plugins.ProtoBuf;  
 using System.Runtime.Serialization;  
 using ServiceStack.ServiceClient.Web;  

namespace client  

  

 public partial class Form1 : Form  

   

private ServiceClientBase _client;  

private const string Url = "http://localhost/servicestack.demo/servicestack/";  

public Form1()  

  

  InitializeComponent();  

  

private void Button1Click(object sender, EventArgs e)  

  

  this._client =  

    new ProtoBufServiceClient(Url);  

  var response = _client.Send<HelloResponse>("GET","/hello",new Hello Name = "ProtoBuf");  

  label1.Text = response.Result;  

   

   

[DataContract]  

public class Hello  

  

[DataMember(Order = 1)]  

public string Name  get; set;   

  

[DataContract]  

public class HelloResponse  

   

[DataMember(Order = 1)]  

public string Result  get; set;   

  



 

【讨论】:

【参考方案3】:

将您的 POCO 类放在同一个命名空间中,应该这样做。

【讨论】:

它在同一个命名空间中。这是什么错误:=> 类型不是预期的,并且无法推断出任何合同:client.Hello 发生在 var response = _client.Send(new Hello Name = "ProtoBuf");

以上是关于使用 Protobuf 格式的 ServiceStack的主要内容,如果未能解决你的问题,请参考以下文章

使用协议缓冲区/Protobuf 的 PInvoke 通用字符串格式

protobuf 版本之间的数据格式兼容性

Protobuf-net 和 WebApi,使用哪种格式通过网络返回数据?

基于google protobuf的gRPC实现

用于解析包含数组格式的 protobuf 数据的二进制文件的 Python API

PHP环境下使用ProtoBuf