Using Protobuf-Net Media Formatter with Web API 2

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.

protobufwebapi01

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.
protobufwebapi02

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.
protobufwebapi03

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://stackoverflow.com/questions/9448453/reading-custom-content-type-f-e-stackoverflow-feeds-using-httpclient-from-web

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://bertt.wordpress.com/2013/10/01/dynamic-pdf-generation-with-asp-net-web-api-and-pdfsharpmigradoc/

http://jflood.net/2012/06/03/asp-net-webapi-upload-image-with-custom-mediatypeformatter/

http://www.tugberkugurlu.com/archive/creating-custom-csvmediatypeformatter-in-asp-net-web-api-for-comma-separated-values-csv-format

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

3 comments

  1. Doron · · Reply

    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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: