The example shows how to setup a Web API 2 service using Protobuf-Net as it Media Formatter and a HttpClient which gets and deserializes the response using Protobuf-Net.
Protobuf is choosen because it’s the fastest Media Formatter at present.
Code: https://github.com/damienbod/WebApi2WebApiContribProtobuf
Web API 2 Server
The server is just a basic Web API MVC 5 project. WebApiContrib.Formatting.ProtoBuf is then added using NuGet.
A simple Protobuf-Net Dto class is required for the client response. This uses the standard Protobuf-Net attributes.
using ProtoBuf; namespace WebAPiProtobuf.Models { [ProtoContract] public class ProtobufModelDto { [ProtoMember(1)] public int Id { get; set; } [ProtoMember(2)] public string Name { get; set; } [ProtoMember(3)] public string StringValue { get; set; } } }
The Formatter is then added to the Web API configuration: config.Formatters.Add(new ProtoBufFormatter());
using System.Web.Http; using WebApiContrib.Formatting; namespace WebAPiProtobuf { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Formatters.Add(new ProtoBufFormatter()); } } }
This is then used in the get method. If ‘application/x-protobuf’ is sent in the Request Header, the content will be returned in a protobuf binary serialization, otherwise per default, a json object is returned.
using System.Collections.Generic; using System.Web.Http; using WebAPiProtobuf.Models; namespace WebAPiProtobuf.Controllers { public class ValuesController : ApiController { // GET api/values/5 public ProtobufModelDto Get(int id) { return new ProtobufModelDto(){Id =1,Name="HelloWorld", StringValue = "My first Protobuf web api service"}; } } }
HttpClient
The HttpClient is implemented in a simple console application. The Web Api Client and WebApiContrib.Formatting.ProtoBuf NuGet packages are added to the application.
The Accept Header ‘application/x-protobuf’ is added to the client and the MediaFormatter ‘ProtoBufFormatter’ is added to the response object, otherwise it cannot be deserialized.
using System; using System.Net.Http; using System.Net.Http.Headers; using WebApiContrib.Formatting; using WebAPiProtobuf.Models; namespace WebClientProtobuf { class Program { static void Main(string[] args) { var client = new HttpClient {BaseAddress = new Uri("http://localhost:49916/")}; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf")); HttpResponseMessage response = client.GetAsync("api/Values/4").Result; if (response.IsSuccessStatusCode) { // Parse the response body. Blocking! var p = response.Content.ReadAsAsync<ProtobufModelDto>(new[] { new ProtoBufFormatter()}).Result; Console.WriteLine("{0}\t{1};\t{2}", p.Name, p.StringValue, p.Id); } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); } Console.ReadLine(); } } }
The object is then displayed in the console.
The Protobuf-Net Media Formatter is very easy to use and gives you maximum performance for a backend service. (Size of data content and speed of serialization)
Links:
http://www.strathweb.com/2013/02/asp-net-web-api-and-protocol-buffers/
https://www.nuget.org/packages/WebApiContrib.Formatting.ProtoBuf/
https://github.com/WebApiContrib/WebApiContrib.Formatting.ProtoBuf
http://code.google.com/p/protobuf/
http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
http://www.intstrings.com/ramivemula/articles/simple-custom-media-formatter-in-asp-net-web-api/
http://blog.ploeh.dk/2012/04/24/VendorMediaTypesWiththeASP.NETWebAPI/
http://byterot.blogspot.ch/2012/04/aspnet-web-api-series-part-5.html
http://blog.maartenballiauw.be/post/2013/03/08/Custom-media-types-for-ASPNET-Web-API-versioning.aspx
http://jflood.net/2012/06/03/asp-net-webapi-upload-image-with-custom-mediatypeformatter/
http://snipplr.com/view/70756/jsonpformatter-for-mvc-webapi/
http://ben.onfabrik.com/posts/atompub-aspnet-web-api-part1
http://www.programmersguide.net/2013/11/using-media-type-formatters-in-aspnet.html
http://www.shujaat.net/2013/12/aspnet-web-api-2-content-negotiation.html
http://stackoverflow.com/questions/19687815/set-default-media-formatter-for-a-webapi-action
http://www.strathweb.com/2012/04/rss-atom-mediatypeformatter-for-asp-net-webapi/
http://www.codeproject.com/Articles/701182/A-Custom-Model-Binder-for-Passing-Complex-Objects
http://www.codeproject.com/Articles/820146/HTTP-Partial-Content-In-ASP-NET-Web-API-Video
[…] Selected excerpt FROM: https://damienbod.wordpress.com/2014/01/11/using-protobuf-net-media-formatter-with-web-api-2/ […]
[…] Consuming protobuf services […]
Hi I was trying that with a XMLHttpRequest from a web client, and it says in Fiddler that he brings me back a JSON.
Do you have an example for using is with a web client requests?
Thanks
It is giving me error of ArrayTypeMismatch in config.Formatters.Add(new ProtoBufFormatter()); runtime. Any suggestion ?
Are your protobuf ids correct?
Hi, Thanks for your prompt reply. I did not get by protobuf Ids correct ? where should i check ? Thanks in advance.
Insallted packages
Microsoft.AspNet.WebApi.Client” version=”4.0.30506.0″
Microsoft.Net.Http” version=”2.0.20710.0″
MVC5″ version=”5.2.3″
Newtonsoft.Json” version=”4.5.11″
protobuf-net” version=”2.0.0.668″
WEBAPI2″ version=”2.2.0″
WebApiContrib.Formatting.ProtoBuf” version=”0.9.5.0″