zoukankan      html  css  js  c++  java
  • 重点关注之自定义序列化方式(Protobuf和Msgpack)

    除了默认的JSON和XML序列化器外,如果想使用其它格式的(比如二进制)序列化器,也是可以的。比如著名的Protobuf和Msgpack,它们都是二进制的序列化器,特点是速度快,体积小。使用方法如下。

    1.定义MediaTypeFormatter,这里以定义MsgPack的formatter为例,主要代码如下。

    image

    2.WebApiConfig中注册,代码如下。

    image

    3.客户端调用(请求头中指定Accept),在.net端调用使用HttpClient,代码如下图。

    image

    附: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);
            }
        }
    }
  • 相关阅读:
    HttpContext.Current.Cache过期使用方法
    IE11下使用IE8
    Sqldbx连接oracle
    XML序列之System.Xml.Serialization
    怎样设置域名带www和不带www都可以访问
    log4net一些配置说明
    部署wcf到IIS时的问题
    spring.net学习(一) 搭建环境,实例化spring.net容器。
    WPF 多语言实现
    C# 类型转换问题
  • 原文地址:https://www.cnblogs.com/mcgrady/p/4701954.html
Copyright © 2011-2022 走看看