简介

现在我们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());
}
完成上面两步, 我们的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 = "",
Subscription = new List<string>() {"news", "picture"}
};
}
return null;
}
}
这里对实体也要进行修改。
 [ProtoContract]
public class UserDto
{
[ProtoMember()]
public string UserName { get; set; } [ProtoMember()]
public string Password { get; set; } [ProtoMember()]
public List<string> Subscription { get; set; }
} [ProtoContract]
public class UserLoginDto
{
[ProtoMember()]
public string UserName { get; set; } [ProtoMember()]
public string Password { get; set; }
}
新建一个测试客户端,控制台就可以,引用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 = "",
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 = "",
}; 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);
}
}
}
运行结果如下:
 
如上我们已经可以看到输出成功

让Web API支持Protocol Buffers的更多相关文章

  1. Go 支持Protocol Buffers的配置

    安装 protoc (The protocol compiler)是由C++写的,支持的 C++.Java.Python.Objective-C.C#.JavaNano.JavaScript.Ruby ...

  2. 通过扩展让ASP.NET Web API支持JSONP

    同源策略(Same Origin Policy)的存在导致了"源"自A的脚本只能操作"同源"页面的DOM,"跨源"操作来源于B的页面将会被拒 ...

  3. 通过扩展让ASP.NET Web API支持W3C的CORS规范

    让ASP.NET Web API支持JSONP和W3C的CORS规范是解决"跨域资源共享"的两种途径,在<通过扩展让ASP.NET Web API支持JSONP>中我们 ...

  4. 让ASP.NET Web API支持POST纯文本格式(text/plain)的数据

    今天在web api中遇到了这样一个问题,虽然api的参数类型是string,但只能接收post body中json格式的string,不能接收原始string. web api是这样定义的: pub ...

  5. 通过微软的cors类库,让ASP.NET Web API 支持 CORS

    前言:因为公司项目需要搭建一个Web API 的后端,用来传输一些数据以及文件,之前有听过Web API的相关说明,但是真正实现的时候,感觉还是需要挺多知识的,正好今天有空,整理一下这周关于解决COR ...

  6. 通过扩展让ASP.NET Web API支持W3C的CORS规范(转载)

    转载地址:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-04.html CORS(Cross-Origin Resource Shari ...

  7. 让ASP.NET Web API支持$format参数的方法

    在不使用OData的情况下,也可以让ASP.NET Web API支持$format参数,只要在WebApiConfig里添加如下三行红色粗体代码即可: using System; using Sys ...

  8. (转)通过扩展让ASP.NET Web API支持JSONP

    原文地址:http://www.cnblogs.com/artech/p/3460544.html 同源策略(Same Origin Policy)的存在导致了“源”自A的脚本只能操作“同源”页面的D ...

  9. [转]让ASP.NET Web API支持$format参数的方法

    本文转自:http://www.cnblogs.com/liuzhendong/p/4228592.html 在不使用OData的情况下,也可以让ASP.NET Web API支持$format参数, ...

随机推荐

  1. jQuery属性/CSS使用例子

    jQuery属性/CSS 1..attr() 获取匹配的元素集合中的第一个元素的属性的值  或 设置每一个匹配元素的一个或多个属性. 例1:获取元素的属性的值 <p title="段落 ...

  2. Linux-HA实战(1)— Heartbeat安装

    接触Heartbeat主要是因为之前项目中使用了TFS,最近想给nameserver做HA,因为TFS官方用的Heartbeat,所以刚好了解下,参考了网络上很多内容,这里简单记录下. 内容 环境和软 ...

  3. Android横屏下Fragment界面重叠问题

    前言: 项目是基于平板开发的,设计的界面是要求横屏展示界面.所以我将所有的Activity都强制设置为横屏 android:screenOrientation="landscape" ...

  4. web开发技术-过滤器

    纪录自己的学习过程,帮助记忆 1.简介 过滤器是服务器端的一个组件,可以接收用户端的请求和响应信息,并且对这些信息进行过滤 过滤器不处理结果,只做一些辅助性操作 2.过滤器的工作原理 3.过滤器的生命 ...

  5. Android Material Design 兼容库的使用

    Android Material Design 兼容库的使用 mecury 前言:近来学习了Android Material Design 兼容库,为了把这个弄懂,才有了这篇博客,这里先推荐两篇博客: ...

  6. 关于web页面性能测量指标与建议

    首先看一个图: 注:右图在我们工作中经常用到 我们专注的web性能指标有那些? 1.页面加载时间 从页面开始加载到页面onload事件触发的时间.一般来说onload触发代表着直接通过HTML引用的C ...

  7. jdb - The Java Debugger

    jdb 是一个简单的命令行调试器,可以调试本地或远程 Java Virtual Machine. jdb [ options ] [ class ] [ arguments ] options 命令行 ...

  8. ORACLE计算表引占用空间大小

    在ORACLE数据库中,如何计算一个表所占用的存储空间呢?我们可以通过系统视图DBA_SEGMENTS.USER_SEGMETNS.DBA_TABLES来查看一个表所占空间的大小,如下所示:   SE ...

  9. mysql中类似indexOf的方法LOCATE()

     LOCATE(substr,str), LOCATE(substr,str,pos) 第一个语法返回substr在字符串str 的第一个出现的位置. 第二个语法返回子符串 substr 在字符串st ...

  10. Solr嵌套子文档的弊端以及一种替代方式

    背景:在考察了多种工具后,我们决定使用solr来作为多标签用户管理体系的查询方案. 原计划:电话,call客,跟进等等记录上报到kafka,然后通过flume+morphline录入到solr中.每一 ...