WCF RESTful服务的Google Protocol Buffers超媒体类型

Protocol Buffers 是在一个很理想的结构化数据的语言中立的序列化格式。你可以考虑一下XML或JSON,但更轻,更小的协议缓冲区。 这种格式的广应用于谷歌不同的系统之间交换数据。

由于其结构化数据的最佳表现,protocol buffers 是一个代表RESTful服务处理的数据很好的选择。要遵循REST的原则, protocol buffers 应作为一个新的超媒体类型的代表。 在当前版本(.NET 4) 的Windows通讯基础(WCF),包含一个新的媒体类型,需要相当数量的努力。 幸运的是,新版本的WCF HTTP堆栈,使媒体类型的WCF编程模型的一等公民,大家可以Glenn Block’s 博客去了解更详细的内容。推荐大家假期可以看下这本书《REST实战》http://book.douban.com/subject/6854551/

下面我们来介绍如何使用Google Protocol Buffers,只定义一个超媒体类型 ProtoBufferFormatter:

自定义超媒体类型是通过创建自定义的MediaTypeFormatter,实现OnWritetoStream() 和 OnReadFromStream() 方法进行序列化和反序列化处理。人们经常认为媒体类型只是在服务端使用,但是它用来在客户端控制序列化和反序列化的要求,下图显示了一个HTTP 请求/响应和媒体类型格式化扮演的角色:

下面的代码是自定义的ProtoBufferFormatter,构造函数里指明了支持的媒体类型 application/x-protobuf。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Http.Formatting;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;

namespace WcfWebFormat.Formatters
{
    public class ProtoBufferFormatter : MediaTypeFormatter
    {
        public ProtoBufferFormatter()
        {
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-protobuf"));
        }

        protected override void OnWriteToStream(Type type, object value, Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, System.Net.TransportContext context)
        {
            Serializer.Serialize(stream, value);
        }

        protected override object OnReadFromStream(Type type, Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders)
        {
            object obj = (RuntimeTypeModel.Default).Deserialize(stream, null, type);
            return obj;
        }

    }
}

如上所示,我们在OnWriteToStream方法中将.NET对象序列化为ProtoBuf格式,在OnReadFromStream方法中将ProtoBuf格式饭序列化为.NET对象。

现在需要给我们的.NET对象加入ProtoBuf 序列化的标签:

using System.Collections.Generic;
using System.Xml.Serialization;
using ProtoBuf;

namespace ContactManager.Resources
{
    [ProtoContract]
    public class Contact
    {
        [ProtoMember(1)]
        public int ContactId { get; set; }
        [ProtoMember(2)]
        public string Name { get; set; }
    }
}

把ProtoBufferFormatter 加入到WCF运行时的超媒体类型集合里。

using Microsoft.ApplicationServer.Http;
using WcfWebFormat.Formatters;

namespace ContactManager
{
    public class ContactManagerConfiguration : HttpConfiguration
    {
        public ContactManagerConfiguration()
        {
            this.Formatters.Add(new ProtoBufferFormatter());
        }
    }
}

修改服务配置,使用ContactManagerConfiguration:

var config = new ContactManagerConfiguration() { EnableTestClient = true };
routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory() { Configuration = config }, typeof(ContactsApi)));

在客户端调用的代码如下:

var serviceUri = new Uri("http://localhost:9000/api/contacts/");
            var httpClient = new HttpClient();
            httpClient.BaseAddress = serviceUri;
            httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-protobuf"));

            var response = httpClient.GetAsync("1").Result;
            Contact obj = (RuntimeTypeModel.Default).Deserialize(response.Content.ReadAsStreamAsync().Result, null, typeof(Contact)) as Contact;

            var formatters = new MediaTypeFormatterCollection() { new ProtoBufferFormatter() };
            var content = new ObjectContent<Contact>(obj, "application/x-protobuf",formatters);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");

            httpClient.PostAsync(serviceUri,content);

即使目前来说Google Protocol Buffers没有XML/JSON那样普及,RESTful服务使用中ProtoBuf无疑是一个非常有效的超媒体类型。祝大家龙年新春愉快,吉祥如意!

本文来自合作伙伴“doNET跨平台”,了解相关信息可以关注“opendotnet”微信公众号

时间: 2024-10-30 06:04:44

WCF RESTful服务的Google Protocol Buffers超媒体类型的相关文章

Google Protocol Buffers快速入门(带生成C#源码的方法)

Google Protocol Buffers是google出品的一个协议生成工具,特点就是跨平台,效率高,速度快,对我们自己的程序定义和使用私有协议很有帮助. Protocol Buffers入门: 1.去 http://code.google.com/p/protobuf/downloads/list 下载一个源代码包和一个已编译好的二进制包 2.找一个Proto示例代码,使用命令 protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/address

Google protocol buffers的Emacs扩展

  通讯层的改造使用了google protocol buffers作为协议体,效率还是挺让人满意.编辑以.proto结尾的语法文件,没有语法高亮很不习惯,幸好protocolbuf提供了vim和emacs的扩展.下载非win32版本的protocol buffers的压缩包里,解压后有个editors目录,里面就是两个扩展文件:proto.vim是提供给vim爱好者的,而protobuf-mode.el就是提供给emacs控的.     安装很简单,将protobuf-mode.el加入你的E

一个简单的WCF RESTFul服务

WCF的REST实例网上很多,这里是我这几天学习并实践通过的,算是个笔记吧 . 1.服务契约 [ServiceContract]public interface IRESTService{} 具体操作定义中,有如下几个参数要注意: 1.WebGet和WebInvoke的区别好像就是Method的定义不同,WebGet使用 "GET",WebInvoke则更灵活. 2.UriTemplate用{value}对应 参数列表. 3.WebMessageFormat包括XML和JSON,网上有

MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明

第1部分 messagepack说明 1.1messagepack的消息编码说明 为什么messagepack比json序列化使用的字节流更少, 可通过图1-1.图1-2有个直观的感觉.   图1- 1 messagepack与json的格式对比1 图1- 2 messagepack与json的格式对比2 messagepack的具体的消息格式如图1-3所示,messagepack的数据类型主要分类两类:固定长度类型和可变长度类型.   图1- 3 messagepack的消息格式 messag

Google Protocol Buffer使用经验分享(一) C++动态消息与静态消息的博弈

写在前面 相信正在浏览这篇文章的同学,一定已经对PB(Protocol buffer)有所了解,所以这里不罗嗦何为PB了. 我自己从去年年底开始对PB的使用逐渐有一些了解,直到在搜索排序框架(iRank)的重构中尝试应用PB,希望能在"数据结构灵活增删改"和"高效的数据传输反序列化"之间求得平衡. 在这过程之中,对PB 动态消息和静态消息的C++使用方式进行了一些调研,对 动态消息 和 静态消息 的优缺点有了进一步了解.通过阅读源代码和实际应用,总结出一些经验,将

使用 Protocol Buffers 代替 JSON 的五个原因 【已翻译100%】

在Ruby和Rails开发者中,面向服务(Service-Oriented)架构有一个当之无愧的名声,它是一个缓解程序规模恶性增长的一个强有力的途径,可在大量应用程序中提取关注点.这些新生小巧的服务通常继续使用Rails或Sinatra,并使用JSON在HTTP上通信.尽管JSON作为一个数据相互交换格式,有很多优点:人类可读.可理解,并通常表现出色. 浏览器和JS并不直接处理数据--尤其是遇到内部服务时.我的观点是,结构化格式,例如谷歌的Protocol Buffers,是一个比JSON在编码

使用 Protocol Buffers 代替 JSON 的五个原因

国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为"中国PE第一股",市值超1000亿元.  ------------------------------------------------------------------------------

java 利用JAX-RS快速开发RESTful 服务

JAX-RS(Java API for RESTful Web Services)同样也是JSR的一部分,详细规范定义见 https://jcp.org/en/jsr/detail?id=311 .从JAVA EE 6开始,已经内置了该技术,跟.NET中的RESTful WCF类似,只要在常规方法上使用一些简单的注解,就可以对外暴露成RESTful 服务. 注:本文运行环境为Jboss EAP 6.x ,其它容器特别是tomcat,并未自带JAX-RS依赖的jar包,如果采用tomcat,需要自

C++程序员Protocol Buffers基础指南

这篇教程提供了一个面向 C++ 程序员关于 protocol buffers 的基础介绍.通过创建一个简单的示例应用程序,它将向我们展示: 在 .proto 文件中定义消息格式 使用 protocol buffer 编译器 使用 C++ protocol buffer API 读写消息 这不是一个关于在 C++ 中使用 protocol buffers 的全面指南.要获取更详细的信息,请参考Protocol Buffer Language Guide 和 Encoding Reference.