重点关注之自定义序列化方式(Protobuf和Msgpack)
除了默认的JSON和XML序列化器外,如果想使用其它格式的(比如二进制)序列化器,也是可以的。比如著名的Protobuf和Msgpack,它们都是二进制的序列化器,特点是速度快,体积小。使用方法如下。
1.定义MediaTypeFormatter,这里以定义MsgPack的formatter为例,主要代码如下。
2.WebApiConfig中注册,代码如下。
3.客户端调用(请求头中指定Accept),在.net端调用使用HttpClient,代码如下图。
附:MessagePackMediaTypeFormatter源代码。
using MsgPack;
using MsgPack.Serialization;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web; namespace HWA.OData.Site.Formatter
{
/// <summary>
/// MsgPack序列化器formatter
/// </summary>
public class MessagePackMediaTypeFormatter : MediaTypeFormatter
{
private readonly string _mime = "application/x-msgpack";
Func<Type, bool> IsAllowedType = (t) =>
{
if (!t.IsAbstract && !t.IsInterface && t != null && !t.IsNotPublic)
return true;
if (typeof(IEnumerable).IsAssignableFrom(t))
return true;
return false;
};
public MessagePackMediaTypeFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue(_mime));
}
public override bool CanWriteType(Type type)
{
if (type == null)
throw new ArgumentNullException("Type is null");
return IsAllowedType(type);
}
public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream stream, HttpContent content, TransportContext transportContext)
{
if (type == null)
throw new ArgumentNullException("type is null");
if (stream == null)
throw new ArgumentNullException("Write stream is null");
var tcs = new TaskCompletionSource<object>();
if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
{
value = (value as IEnumerable<object>).ToList();
}
var serializer = MessagePackSerializer.Create<dynamic>();
serializer.Pack(stream, value);
tcs.SetResult(null);
return tcs.Task;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
{
var tcs = new TaskCompletionSource<object>();
if (content.Headers != null && content.Headers.ContentLength == 0)
return null;
try
{
var serializer = MessagePackSerializer.Create(type);
object result;
using (var mpUnpacker = Unpacker.Create(stream))
{
mpUnpacker.Read();
result = serializer.UnpackFrom(mpUnpacker);
}
tcs.SetResult(result);
}
catch (Exception e)
{
if (formatterLogger == null) throw;
formatterLogger.LogError(String.Empty, e.Message);
tcs.SetResult(GetDefaultValueForType(type));
}
return tcs.Task;
}
public override bool CanReadType(Type type)
{
if (type == null)
throw new ArgumentNullException("type is null");
return IsAllowedType(type);
}
}
}
重点关注之自定义序列化方式(Protobuf和Msgpack)的更多相关文章
- WeihanLi.Redis自定义序列化及压缩方式
WeihanLi.Redis自定义序列化及压缩方式 Intro WeihanLi.Redis 是基于 StackExchange.Redis 的扩展,提供了一些常用的业务组件和对泛型的更好支持,默认使 ...
- java序列化和反序列化及序列化方式
平时我们在Java内存中的对象,是无 法进行IO操作或者网络通信的,因为在进行IO操作或者网络通信的时候,人家根本不知道内存中的对象是个什么东西,因此必须将对象以某种方式表示出来,即 存储对象中的状态 ...
- .Net Core 自定义序列化格式
序列化对大家来说应该都不陌生,特别是现在大量使用WEBAPI,JSON满天飞,序列化操作应该经常出现在我们的代码上. 而我们最常用的序列化工具应该就是Newtonsoft.Json,当然你用其它工具类 ...
- Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- Java Serializable接口(序列化)理解及自定义序列化
1 Serializable接口 (1)简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存在数据库,内存,文件等),然后可以在适当的时候再将其状态恢复(也就是反 ...
- Android进程通信之一:两种序列化方式
2月下旬辞职了,去海南度假到现在,领略了一把三亚风情也算任性和 然而这样任性带来的后果就是..不行了我必须吐槽一句.. 没毕业的找工作就这么难嘛!投了57家一家面试机会都没有,好歹给个面试机会啊!!本 ...
- SpringBoot修改Redis序列化方式
前言 由于Springboot默认提供了序列化方式并不是非常理想,对于高要求的情况下,序列化的速度和序列化之后大小有要求的情况下,不能满足,所以可能需要更换序列化的方式. 这里主要记录更换序列化的方式 ...
- 几种序列化协议(protobuf,xstream,jackjson,jdk,hessian)相关数据对比
测试结果 序列化数据对比 bytes字节数对比 具体的数字: protobuf jackson xstream Serializable hessian2 hessian2压缩 hessian1 ...
- 自定义兼容多种Protobuf协议的编解码器
<从零开始搭建游戏服务器>自定义兼容多种Protobuf协议的编解码器 直接在protobuf序列化数据的前面,加上一个自定义的协议头,协议头里包含序列数据的长度和对应的数据类型,在数据解 ...
随机推荐
- WdatePicker.js 日历点击时,触发自定义方法 ,可以调用自己的函数。
问题: 在选择日期后,没有提交按钮,得到日期后,就可以把日期传到后台,然后就可以得到数据. 方法: 在input 标签中加入onfocus ,就可以了. wdatePicker();可以自定义事件函数 ...
- redis问题
phalcon 在读取数据的时候如果说reids数据库没有连接成功的话,则会显示一下错误:
- 关于Java控制台输入输出乱码问题
产生原因:因为这个开源项目的默认字符编码为UTF-8,所以我的控制台的字符编码也自动变成了UTF-8,而键盘的输入流的默认格式是GBK格式,这样就造成了在GBK转UTF-8的过程中产生的奇数乱码错误( ...
- Spring对hibernate的事物管理
把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理.一 ...
- mysql 大数据量的处理
insert 1.过滤一段时间内重复的数据2.数据缓存起来,批量写入 select1.使用分区表2.主主复制,连接不同的mysql3.建立索引4.定时求平均值,写入一个新的表中
- Python中的__new__()方法的使用
__new__() 函数只能用于从object继承的新式类. 先看下object类中对__new__()方法的定义: class object: @staticmethod # known cas ...
- android学习---- WindowManager 接口 (
The interface that apps use to talk to the window manager. 这个接口用于与 window manager (窗口管理器, 应用框架层) 进行交 ...
- vi编辑器简单应用(摘抄)
摘抄于 vi编辑器的使用 (2) (3) 1 vi编辑器的基本使用 1.1 vi的启动 打开: $ vi example.c 只读打开 $ vi –R example.c 1.2 vi的工作模式 1. ...
- Linux命令:traceroute(windows中为tracert)
通过traceroute 我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不 ...
- as的Enter_Frame与Timer
As3中的Timer和Event.EnterFrame是有明显的区别的. Evnet.EnterFrame是定时间隔多少时间出发.如果执行时间比间隔时间长,则会间隔执行时间这么久. 举个例子: Fla ...