zoukankan      html  css  js  c++  java
  • 《ASP.NET Core跨平台开发从入门到实战》Web API自定义格式化protobuf

    《ASP.NET Core跨平台开发从入门到实战》样章节 Web API自定义格式化protobuf。

    样章

    Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。

    它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

    以下将实现一个格式化程序返回protobuf 格式。

    首先新建一个ASP.NET Core Web Application应用程序名为 ProtobufFormat,选择Web API模板。

    添加protobuf-net 引用。使用NuGet 命令行或者NuGet包管理器安装。

    NuGet 命令行:Install-Package protobuf-net。

    添加一个ProtobufFormatter 类

        public class ProtobufFormatter : OutputFormatter

        {

            public string ContentType { get; private set; }

            public ProtobufFormatter()

            {

                ContentType = "application/proto";

                SupportedMediaTypes.Add(Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/proto"));

            }

            public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)

            {

                if (context == null)

                {

                    throw new ArgumentNullException(nameof(context));

                }

                var response = context.HttpContext.Response;

                Serializer.Serialize(response.Body, context.Object);

                return Task.FromResult(0);

            }

    }

    继承OutputFormatter ,然后实现WriteResponseBodyAsync 方法,初始化时赋值ContentType 以及添加支持MediaType。

    在WriteResponseBodyAsync 方法中获取Response,调用protobuf-net的Serialize方法将Object序列化至输出内容。protobuf 在序列化时必须指定顺序,不然会序列化失败。

    下面添加一个User类,来实现protobuf 实体。

        [ProtoContract]

        public class User

        {

            [ProtoMember(1)]

            public int Id { get; set; }

            [ProtoMember(2)]

            public string Name { get; set; }

            [ProtoMember(3)]

            public int Age { get; set; }

        }

    类上需要加上ProtoContract 特性,然后字段需加上ProtoMember特性,并指定顺序。这样的一个类才能被序列化为protobuf 格式。

    然后更改ValuesController控制器里的操作,使之输出protobuf。

        [Route("api/[controller]")]

        public class ValuesController : Controller

        {

            private IEnumerable<User> Users;

            public ValuesController()

            {

                Users= new User[] {

                    new User() { Id=1,Name="book",Age=1},

                    new User() { Id=2,Name="asp.net core",Age=10},

                };

            }

            // GET api/values

            [HttpGet]

            [Produces("application/proto")]

            public IEnumerable<User> Get()

            {

                return Users;

            }

            // GET api/values/5

            [HttpGet("{id}")]

            [Produces("application/proto")]

            public User Get(int id)

            {

                return Users.FirstOrDefault(r => r.Id == id);

            }

        }

    在每个操作上加上Produces特性,里面值为application/proto,也就是刚刚设置的 ContentType。然后直接返回对应的对象结果即可。

    如果现在运行应用程序,访问api/values 会发现没有返回结果,因为还需要在AddMvc中添加对应的格式化。

    打开Startup 类中的ConfigureServices方法,将services.AddMvc() 更改为如下:

            public void ConfigureServices(IServiceCollection services)

            {

                services.AddMvc(option=> {

                    option.OutputFormatters.Add(new ProtobufFormatter());

                });

            }

    添加输出格式化程序ProtobufFormatter。

    现在再运行应用程序,访问api/values 会返回一个二进制文件,里面也就包含序列化之后的数据。

    可以新建测试程序来模拟调用Web API来检查序列化是否正确。

    新建一个.NET Core控制台应用程序,在Program.cs 中将Main方法更改为如下代码:

            public static void Main(string[] args)

            {

                HttpClient client = new HttpClient();

                var stream=client.GetStreamAsync("http://localhost:5000/api/values").Result;

                var users=Serializer.Deserialize<List<User>>(stream);

                foreach (var item in users)

                {

                    Console.WriteLine($"ID:{item.Id}-Name:{item.Name}-Age:{item.Age}");

                }

                Console.ReadKey();

            }

    并将User类复制到该项目。

    代码为访问http://localhost:5000/api/values获得结果,然后将其反序列化为实体对象。遍历对象,并展示出来。

    首先运行Web API 应用程序,然后运行测试控制台应用程序。控制台应用程序会显示如下:

    ID:1-Name:book-Age:1

    ID:2-Name:asp.net core-Age:10

    表示成功访问并得到结果反序列化实体对象成功。如此,自定义格式化程序ProtobufFormatter,也就成功实现。同理还可以实现其他所需要的格式化程序。

    感悟

    《ASP.NET Core跨平台开发从入门到实战》 成功出版,经历时间还是蛮长的。本书是基于.NET Core 1.0所著。

    .NET Core发展快速,现在新的VS2017也发布了,导致书中部分内容可能不大适用。但是理论部分及代码还是未过时。

    本书的定位为 入门书籍 ,想系统了解ASP.NET Core 及学习ASP.NET Core 有所帮助。

    可以点击文章底部或左边的购买链接查看详细的目录和购买。

    活动

    赠书活动,本次赠送6本《ASP.NET Core跨平台开发从入门到实战》。

    活动规则:

    在下方评论或转发至微博并在下方评论留言。

    中奖楼层规则:

    截止 4月21日 12:00 楼层数-(楼层数/6-1) 递减下去。 如:最终50层 50-(50/6-1)=43 43-7=36 36-7=29 29-7=22 22-7=15 15-7=8

    每人最多评论三次,超过属于刷屏,顺延至下一位。

    4月21日 13:00 公布 公布中奖以后,大家将地址和联系方式私信于我。

    4月21日 12:30 更新

    152-(152/6-1)=128 @sigmud
    128-24=104 @IT胡小帅
    104-24=80 顺延至下一位 81 @张君度
    80-24=56 @麦梗上的代码
    56-24=32 @wlf921
    32-24=8 @。流年。 
    恭喜以上博友获得 《ASP.NET Core跨平台开发从入门到实战》一本。
    感谢大家的热情支持,以上朋友请将地址和联系方式尽快私信于我,我会在这周末发出。

    如果你觉得本文对你有帮助,请点击“推荐”,谢谢。

  • 相关阅读:
    Object-C,NSSet,不可变集合
    NYIST 860 又见01背包
    NYIST 1070 诡异的电梯【Ⅰ】
    HDU 1542 Atlantis
    HDU 4756 Install Air Conditioning
    CodeForces 362E Petya and Pipes
    HDU 4751 Divide Groups
    HDU 3081 Marriage Match II
    UVA 11404 Palindromic Subsequence
    UVALIVE 4256 Salesmen
  • 原文地址:https://www.cnblogs.com/linezero/p/6736950.html
Copyright © 2011-2022 走看看