插上腾飞的翅膀:为asp.net core添加protobuf支持

没时间解释了,快上车。

通过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",
                 https://i.cnblogs.com/EditCategories.aspx?catid=1       Enum = TestEnum.Banana
                    },
                    new TestDto
                    {
                        Id = Guid.NewGuid(),
                        Tag = long.MaxValue - 5,
                        CreateTime = DateTime.Now,
                        Name = "11",
                        Enum = TestEnum.Pear
                    }
                }
            }
        };
    }
}

为什么要用protobuf?

因为快……在我们这边使用业务数据的测试中,protobuf的序列化/反序列化性能大概是Json.net的三倍,序列化后的体积大概只有Json的二分之一,这可以在相当程度上提高webapi的吞吐性能。

protobuf的缺点

DTO层必须引用protobuf-net来添加特性,这在一定程度上导致了代码的侵入。基本上DTO属于POCO,依赖第三方包的话总觉得有点不贞洁……另外就是protobuf序列化后的数据不具有可视化,因此如果是使用消息队列或者请求监控的地方,就要综合考虑protobuf是否适合使用场景。

原理

asp.net core是基于中间件方式来实现,其自带默认的JsonFormater(基于Json.net),asp.net core会根据content type来选择对应的Formater来处理对象的序列化,当中包括InputFormatter(反序列化)和OutputFormatter(序列化)。因此除了protobuf,我们还可以添加或者替换其它的序列化方式,例如使用Jil来代替Json.net来提高Json性能。

以上实现以及Demo和测试的源代码已放到GitHub上。

最后给大家拜个晚年,祝大家新年快乐~

原文地址:https://www.cnblogs.com/Mutuduxf/p/8457011.html

时间: 2024-08-30 00:41:08

插上腾飞的翅膀:为asp.net core添加protobuf支持的相关文章

软件定制开发,给你的idea插上腾飞的翅膀

软件定制开发,给你的idea插上腾飞的翅膀 2017互联网创业项目都有哪些?创业意识及其能力是这个时代发展的引擎,因而很多实事与理论指出知识经济的时代即创业的时代. 知识经济时代你的一个好的想法也能给你创造价值.创业就是从你的一个想法出来的. 创业的魅力也许就在于这个神秘的Idea变成现实的过程.Idea是创业成功中最核心.最关键的.最没规律可循的一个环节.当你有了一个好的idea后,你会如何去实现它呢? 这时候你就得找专业的人去帮你出谋划策,最近有一个互联网平台专门做将客户的idea变成具有商

网站制作为公司业绩插上腾飞的翅膀

网站,是一个企业在竞争中能够不断发展的一个重要因素,很多企业之所以能够在经济浪潮中走到现在,在很大程度上是因为有一个非常棒的网站建设,一个好的网站会使您的业绩得到提升,那么,如何进行网站制作呢,接下来,达沃斯建站 (www.hzdavos.com)为你详细介绍一下. 网站制作,您可以选择自己进行免费建站,也可以请专业的网站建设公司来寻求帮助,对他们支付一定的手续费,一般来说,请专业的公司来进行制作和推广,每年的维护费用和制作费用总共大致需要一千多元钱,这笔费用其实相对于盈利比较好的公司来说,并不

ASP.NET Core 使用protobuf

ASP.NET Core 使用protobuf在一些性能要求很高的应用中,使用protocol buffer序列化,优于Json.而且protocol buffer向后兼容的能力比较好. 由于Asp.net core 采用了全新的MiddleWare方式,因此使用protobuf序列化,只需要使用Protobuf-net修饰需要序列化的对象,并在MVC初始化的时候增加相应的Formatter就可以了. MVC Controller 的Action返回对象时,MVC回根据用户的Request He

Mono ASP.NET core 添加 Entity Framework

Mono ASP.NET core 添加 Entity Framework 的时候, 仅仅用 Nuget 添加  System.Data.Entity 是没用的. 还需要添加一个叫做 EntityFramework 的包才能使用.

在Mac上开发使用yoeman构建Asp.net core项目并且实现分层引用

1.Yoeman? yoeman是一个自动化脚手架工具.它提供很多generator,generator相当于VisualStudio的模板,用来初始化项目.更多的就不多说了,写一遍都写不完,自己看吧. http://yeoman.io/ 2.安装 yoeman 安装yoman之前你需要先安装npm.npm是一个JavaScript的包管理工具,一般跟nodejs配合使用.https://docs.npmjs.com/getting-started/what-is-npm 使用npm来安装yoe

给PLSQL插上飞翔的翅膀-PLSQL优化

60-80% of database performance issues are related to poorly performing SQL.60-80%的数据库性能问题要归结于生产中糟糕的SQL语句! 以此一文来总结笔者近10多年来的工作经验并基于最主要的也是最有效的对于Oracle数据库中的RBO.CBO.索引.WHERE条件进行解说同一时候配以大量案例来帮助读者从此文中学到的相关的理论知识高速的运用到其正在从事的生产环境中的优化过程中去. 优化的理论基础 通过Select Coun

让用户研究插上数据的翅膀

转载:http://spss-market.r.blog.163.com/blog/static/73142268201183013022414/ 无论是产品经理.设计师.工程师,大家都是为用户服务的.用户各有所好.你喜欢这个,我喜欢那个,也有我们都喜欢的.那么在用户的心理隐藏着什么样的秘密呢?要想发现其中的奥妙,通常有两种方式:定性研究.定量分析.定性的信息告诉你为什么会发生,它灵活.快速.细节丰富,但缺乏普遍性,我们能听到的只能是少部分用户的声音,他们是否代表大多数用户是无从判断的.另一种方

给Eclipse、Android Studio插上Vim的翅膀

最近在学习使用Vim--传说中的,编辑器之神!一周多了,感觉Vim确实是非常强大,尤其是在处理文本数据的时候,不是一点点的牛逼:仔细想想,平常写的代码,不都是文本数据吗?那么如果用Vim 再配合 编辑器强大的联想.补全功能,岂不是非常爽? 因此,查找了相关的资料,找到了一篇文章: Eclipse 和 Vim 顺利的给Eclipse 集成了 Vim,Android Studio 就更不用说了,在Plugins里面一搜,直接就装上了! 试了个水,感觉太强大了! 版权声明:本文为博主原创文章,未经博主

IMXRT1061“智能手环”为工业制造插上“隐形的翅膀”

从生活到工业,数字技术无处不在.在生活中,数字技术的发展促使互联网得到巨大的创新,"智慧生活"充斥在生活场景里的各个角落.随着健身热,各种智能运动手环开始风靡全球,不仅可以记录步数,还可以帮助我们分析每天的运动健康情况.如今,工业设备也能"戴"上这样的"智能手环". 所谓的"工业手环"并非是类似于人们常用的健康手环一样的东西,而是专为工业环境而打造,一种能够检测工业设备"健康"的智能硬件设备. 只需要将&q