首页 > 编程 > .NET > 正文

如何为asp.net core添加protobuf支持详解

2024-07-10 12:48:48
字体:
来源:转载
供稿:网友

前言

在一些性能要求很高的应用中,使用protocol buffer序列化,优于Json。而且protocol buffer向后兼容的能力比较好。

由于Asp.net core 采用了全新的MiddleWare方式,因此使用protobuf序列化,只需要使用Protobuf-net修饰需要序列化的对象,并在MVC初始化的时候增加相应的Formatter就可以了。

没时间解释了,快上车。

通过NuGet获取Zaabee.AspNetCoreProtobuf

Install-Package Zaabee.AspNetCoreProtobuf

在Startup.cs文件中修改ConfigureServices方法

public void ConfigureServices(IServiceCollection services){  services.AddMvc(options => { options.AddProtobufSupport(); });}

搞掂……这时候你就可以通过application/x-protobuf的content-type来让asp.net core使用protobuf来进行序列化/反序列化。

测试代码

在asp.net core项目中添加以下DTO

[ProtoContract]public class TestDto{  [ProtoMember(1)] public Guid Id { get; set; }  [ProtoMember(2)] public string Name { get; set; }  [ProtoMember(3)] public DateTime CreateTime { get; set; }  [ProtoMember(4)] public List<TestDto> Kids { get; set; }  [ProtoMember(5)] public long Tag { get; set; }  [ProtoMember(6)] public TestEnum Enum { get; set; }}public enum TestEnum{  Apple,  Banana,  Pear}

新建一个XUnit项目,通过Nuget引用Microsoft.AspNetCore.TestHost,建立一个测试类

public class AspNetCoreProtobufTest{  private readonly TestServer _server;  private readonly HttpClient _client;  public AspNetCoreProtobufTest()  {    _server = new TestServer(      new WebHostBuilder()        .UseKestrel()        .UseStartup<Startup>());    _client = _server.CreateClient();  }  [Fact]  public void Test()  {    // HTTP Post with Protobuf Response Body    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));    var dtos = GetDtos();    var stream = new MemoryStream();    ProtoBuf.Serializer.Serialize(stream, dtos);    HttpContent httpContent = new StreamContent(stream);    // HTTP POST with Protobuf Request Body    var responseForPost = _client.PostAsync("api/Values", httpContent);    var result = ProtoBuf.Serializer.Deserialize<List<TestDto>>(      responseForPost.Result.Content.ReadAsStreamAsync().Result);    Assert.True(CompareDtos(dtos,result));  }  private static bool CompareDtos(List<TestDto> lstOne, List<TestDto> lstTwo)  {    lstOne = lstOne ?? new List<TestDto>();    lstTwo = lstTwo ?? new List<TestDto>();    if (lstOne.Count != lstTwo.Count) return false;    for (var i = 0; i < lstOne.Count; i++)    {      var dtoOne = lstOne[i];      var dtoTwo = lstTwo[i];      if (dtoOne.Id != dtoTwo.Id || dtoOne.CreateTime != dtoTwo.CreateTime || dtoOne.Enum != dtoTwo.Enum ||        dtoOne.Name != dtoTwo.Name || dtoOne.Tag != dtoTwo.Tag || !CompareDtos(dtoOne.Kids, dtoTwo.Kids))        return false;    }    return true;  }  private static List<TestDto> GetDtos()  {    return new List<TestDto>    {      new TestDto      {        Id = Guid.NewGuid(),        Tag = long.MaxValue,        CreateTime = DateTime.Now,        Name = "0",        Enum = TestEnum.Apple,        Kids = new List<TestDto>        {          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 1,            CreateTime = DateTime.Now,            Name = "00",            Enum = TestEnum.Banana          },          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 2,            CreateTime = DateTime.Now,            Name = "01",            Enum = TestEnum.Pear          }        }      },      new TestDto      {        Id = Guid.NewGuid(),        Tag = long.MaxValue - 3,        CreateTime = DateTime.Now,        Name = "1",        Enum = TestEnum.Apple,        Kids = new List<TestDto>        {          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 4,            CreateTime = DateTime.Now,            Name = "10",            Enum = TestEnum.Banana          },          new TestDto          {            Id = Guid.NewGuid(),            Tag = long.MaxValue - 5,            CreateTime = DateTime.Now,            Name = "11",            Enum = TestEnum.Pear          }        }      }    };  }}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表