Part 1: Improve ASP.net WebApi performance with protocol buffer

In a constantly moving market performance is a factor to success. I will focus this article on performance of ASP.net WebApi. Especially the format ‘Protocol Buffer’. When comparing xml, json and protocol buffer I was amazed. So I hope that this article will amaze you!

Protocol buffer doesn’t use tags to identify its properties. It identifies the properties by its order. So both the client and server side need to know the order of the properties to be able to communicate. The payload of the response is much smaller because it doesn’t pass the name of the properties.

To add Protocol Buffer as a format for your ASP.net WebApi project follow these steps.

1) Add the NuGet package ‘WebApiContrib.Formatting.ProtoBuf’

2) Add the following line before or in the WebApiConfig.Register function. And do this for each object that you would like to be formatted by Protocol Buffer

ProtoBufFormatter.Model.Add(typeof(Customer), false);

3) After these lines you have to define the order of the properties. Here is how I do it.

foreach (MetaType type in ProtoBufFormatter.Model.GetTypes())
{
    int i = 1;
    foreach (var property in type.Type.GetProperties())
    {
        if (property.CanWrite && property.CanRead)
        {
            type.Add(i, property.Name);
            i++;
        }
    }
}

4) Add the ProtoBufFormatter to the default formatter collection of ASP.net WebApi

config.Formatters.Add(new ProtoBufFormatter());

Example:

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class CustomerController : ApiController
    {
        public IEnumerable<Customer> Get()
        {
            return new List<Customer>()
            {
                new Customer() { Id = 1, Name = "Chuck Norris", },
                new Customer() { Id = 2, Name = "Bruce Lee", },
                new Customer() { Id = 3, Name = "Sylvester Stallone", },
                new Customer() { Id = 4, Name = "Jason Statham", },
                new Customer() { Id = 5, Name = "Jet Li", },
                new Customer() { Id = 6, Name = "Wesly Snipes", },
                new Customer() { Id = 7, Name = "Mel Gibson", },
                new Customer() { Id = 8, Name = "Arnold Schwarzenegger", },
                new Customer() { Id = 9, Name = "Harrison Ford", },
                new Customer() { Id = 10, Name = "Antonio Banderas", },
            };
        }
    }
  • /api/customer with content type ‘application/xml
    • => response body size 734 bytes
  • /api/customer with content type ‘application/json
    • => response body size 322 bytes (2,28 times smaller then xml)
  • /api/customer with content type ‘application/x-protobuf
    • => response body size 190 bytes (3,86 times smaller then xml)

ASP.net WebApi protocol buffer comparison

Happy coding🙂

ASP.net WebApi with apartment state STA (Single Thread Apartment)

For one of our customers we were asked to created a webservice that was able to talk to venice. We immediately thought of ASP.net WebApi to create this webservice.

After some trial and error we got the webservice running but it was very slow. We used a perfomance analysis tool and saw that the communication with the Venice SDK was the bottleneck.

When integrating with Venice we need to reference the COM dll that UNIT4 provides. Apparently there COM dll is very sensitive about the apartment state of the calling thread. They recommend using a Single Threaded Apartment. But how can we achieve ApartmentState.STA during a webservice call?

After some searching on the web we found a comparable problem. So we came up with the following solution.

1) Add the NuGet package ‘MSFT.ParallelExtensionsExtras’

2) Add the following classes to your solution

    public static class TaskFactoryExtensions
    {
        private static readonly TaskScheduler _staScheduler = new StaTaskScheduler(numberOfThreads: 1);

        public static Task<TResult> StartNewSta<TResult>(this TaskFactory factory, Func<TResult> action)
        {
            return factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, _staScheduler);
        }
    }

    public class StaThreadEnabledHttpActionInvoker : ApiControllerActionInvoker
    {
        public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext context, CancellationToken cancellationToken)
        {
            return Task.Factory.StartNewSta(() => base.InvokeActionAsync(context, cancellationToken).Result);
        }
    }

3) Replace the standard HttpActionInvoker service of ASP.net WebApi

config.Services.Replace(typeof(IHttpActionInvoker), new StaThreadEnabledHttpActionInvoker());

Happy coding🙂

Hello World!

Hello World! My name is Sander Wollaert. I live in Belgium. I’m employed as a Software Architect at ICORDA. This blog will be a collection of tips and best practices that every developer could use.

My blog post will focus on .NET development with the following technologies:

  •  WinForms (with DevExpress)
  • ASP.net WebApi
  • HTML5 + JS
  • SQL Server

I’ll also post about integration with 2 ERP systems:

  • UNIT4 Venice
  • SAP Business One

I hope you’ll enjoy my posts!