• 让Web API支持Protocol Buffers


    现在我们Web API项目基本上都是使用的Json作为通信的格式,随着移动互联网的兴起,Web API不仅其他系统可以使用,手机端也可以使用,但是手机端也有相对特殊的地方,网络通信除了wifi,还有蜂窝网络比如2G/3G,当手机处于这种网络环境下并且在一些偏僻或者有建筑物阻挡的地方,网络会变得非常差,之前我有测试过ProtoBuf和Json在序列化和反序列化上性能的对比,通过测试发现ProtoBuf在序列化和反序列化以及序列化后字节的长度和其他的框架相比都有很大的优势,所以这篇文章准备让Web API也支持Protocol Buffers。

    要让Web API支持ProtoBuf就需在Web API的HttpConfigurationFormatters中注册MediaTypeFormatter,这里已经有现成的解决方案,我们直接使用。 
    1. 从nuget上下载WebApiContrib.Formatting.ProtoBuf.
    2. 修改配置,新增config.Formatters.Add(new ProtoBufFormatter());
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",   //修改路由规则
                    defaults: new { id = RouteParameter.Optional }
                );
    
                config.Formatters.Add(new ProtoBufFormatter());
            }
    View Code
    完成上面两步, 我们的Web API就已经支持了ProtoBuf,我们可以新建一个Controller来进行测试。
     public class UserController : ApiController
        {
    
            /// <summary>
            /// 注册用户
            /// </summary>
            /// <param name="userDto"></param>
            /// <returns></returns>
            public string Regist(UserDto userDto)
            {
                if (!string.IsNullOrEmpty(userDto.UserName) && !string.IsNullOrEmpty(userDto.Password))
                {
                    return "regist success";
                }
                return "regis error";
            }
    
            //登陆
            public string Login(UserLoginDto userLoginDto)
            {
                if (userLoginDto.UserName == "sa")
                {
                    return "login success";
                }
                return "loign fail";
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="id"></param>
            /// <param name="userName"></param>
            /// <returns></returns>
            public UserDto Get(string userName)
            {
                if (!string.IsNullOrEmpty(userName))
                {
                    return new UserDto()
                    {
                        UserName = "sa",
                        Password = "123",
                        Subscription = new List<string>() {"news", "picture"}
                    };
                }
                return null;
            }
        }
    View Code
    这里对实体也要进行修改。
     [ProtoContract]
        public class UserDto
        {
            [ProtoMember(1)]
            public string UserName { get; set; }
    
            [ProtoMember(2)]
            public string Password { get; set; }
    
            [ProtoMember(3)]
            public List<string> Subscription { get; set; }
        }
    
      [ProtoContract]
        public class UserLoginDto
        {
            [ProtoMember(1)]
            public string UserName { get; set; }
    
            [ProtoMember(2)]
            public string Password { get; set; }
        }
    View Code
    新建一个测试客户端,控制台就可以,引用WebApiContrib.Formatting.ProtoBuf和Web Api Client
    将我们刚才创建的Dto复制到客户端,测试代码如下:
      static void Main(string[] args)
            {
                var client = new HttpClient { BaseAddress = new Uri("http://192.168.16.9:8090/") };
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
    
                Regist(client);
                Console.WriteLine("===================================");
                Login(client);
                Console.WriteLine("===================================");
                GetUser(client);
                Console.WriteLine("===================================");
                Console.ReadLine();
            }
    
            private static void Regist(HttpClient client)
            {
                //注册
                var userDto = new UserDto()
                {
                    UserName = "sa",
                    Password = "123456",
                    Subscription = new List<string>() { "news", "picture" }
                };
    
                HttpResponseMessage response = client.PostAsync("api/User/Regist", userDto, new ProtoBufFormatter()).Result;
    
                if (response.IsSuccessStatusCode)
                {
                    var p = response.Content.ReadAsAsync<string>(new[] { new ProtoBufFormatter() }).Result;
                    Console.WriteLine(p);
                }
            }
    
            private static void Login(HttpClient client)
            {
    
                //登陆
                var userlogin = new UserLoginDto()
                {
                    UserName = "sa",
                    Password = "123456",
                };
    
                HttpResponseMessage response = client.PostAsync("api/User/login", userlogin, new ProtoBufFormatter()).Result;
                if (response.IsSuccessStatusCode)
                {
                    var p = response.Content.ReadAsAsync<string>(new[] { new ProtoBufFormatter() }).Result;
                    Console.WriteLine(p);
                }
            }
    
            private static void GetUser(HttpClient client)
            {
    
                HttpResponseMessage response = client.GetAsync("api/User/Get?userName=sa").Result;
    
                if (response.IsSuccessStatusCode)
                {
                    var p = response.Content.ReadAsAsync<UserDto>(new[] { new ProtoBufFormatter() }).Result;
    
                    Console.WriteLine(p.UserName + " " + p.Password);
                    foreach (var s in p.Subscription)
                    {
                        Console.WriteLine(s);
                    }
                }
            }
    View Code
    运行结果如下:
     
    如上我们已经可以看到输出成功
  • 相关阅读:
    笔记20200430:异常机制
    笔记20200429:面向对象
    笔记20200429:数组
    笔记20200428:方法的定义及调用、重装、命令行参数、可变参数、递归
    笔记20200427:javadoc文档、Scanner、顺序结构、选择结构、循环结构
    CSS+DIV入门第一天基础视频 CSS选择器层叠性和继承性
    网站实战 从效果图开始CSS+DIV 布局华为网站
    CSS中的间距设置与盒子模型
    CSS选择器
    CSS颜色及文本字体
  • 原文地址:https://www.cnblogs.com/beyondbit/p/4778330.html
Copyright © 2020-2023  润新知