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跨平台开发从入门到实战》一本。
    感谢大家的热情支持,以上朋友请将地址和联系方式尽快私信于我,我会在这周末发出。

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

  • 相关阅读:
    移动端rem布局
    父子组件通信
    拦截器
    Vue路由教程
    使用var和let的区别
    数组去重的几种方法
    利用位运算进行权限控制
    线程基础
    关于get请求的乱码问题
    nuxt.js Navigating to current location ("/xxx") is not allowed
  • 原文地址:https://www.cnblogs.com/linezero/p/6736950.html
Copyright © 2011-2022 走看看