Posts

SignalR Scaleout with SQL Server in Azure

A project for one of our customers recently had this scenario where mobile clients posted updates to a REST-backend running on one site and we needed to notify all clients browsing a different site. The first technique that came into mind was SignalR but we had only used it within the same app before. Now we’d like to share a hub across apps.

Fortunately, the solution was very simple, SignalR supports CORS and scaling out with SQL server out of the box. All you need to install is the following two nuget packages.

PM> Install-Package Microsoft.AspNet.SignalR
PM> Install-Package Microsoft.AspNet.SignalR.SqlServer

This is truly powerful and the SignalR-team has done a great job making it easy to use. There’s an excellent official guide here. Here’s a screencast to show how quickly and easy you can get it up and running in Azure from scratch.

 

Source code @ https://github.com/ajtowf/signalrlab/

 

Hope you find it useful!

 

Keywords : VS2013, Azure, SignalR, WebApi, MVC, OWIN, SQL Server

ASP.NET MVC and AngularJS

I really think these two frameworks don’t mesh together too well and this blog post is me trying to explain why.

If you’re used to traditional MVC with full page refreshes, views, server side partials etc. and you’ve decided that you want to use a bit of angular inside your pages you are going to be very frustrated. Angular is really best for single page applications (SPA seems to be a buzz word for the moment). If you just want some javascript goodness just use knockoutjs.

I’d suggest using WebApi instead. This is what I’ve found out works best.

  • The server side actions on the ApiController should only return JSON data to the client and be consumed by ajax calls from angular.
  • Stop thinking in terms of razor and writing C# code in your views and working with the @model passed from the controller.
  • Only have one razor page for your app (Index.cshtml), no views, no partials. Load everything on the index page.
  • Do not use the MVC routing, let angular perform the dynamic page updates.
You might ask yourself; why use razor at all? Well the Web.Optimization bundle is quite neat and I’ve grown quite attached to it :-)
 
For SPAs sure go ahead and use angular it’s awesome. But stick with angular/javascript for front-end and use WebApi for back-end if you’ve decided that you want to try out angular on top of asp.net.
 
Also imo SPAs should be fairly small, if you know your project will be fairly big SPA really isn’t the way to go. It could be me just having a hard time to adapt since I’m used to hooking everything up in a spaghetti of document.ready-functions :-P I’ve always been a “back-end / do it on the server / use as much static typing as possible” kind of guy but perhaps that’s changing, especially with tools like TypeScript which is a must in all my web projects nowadays.
 
I might add that I also have experience using angular together with jQuery mobile when developing a scorecard app for golf (golf-caddie.se) which wasn’t too pleasant but that’s another blog post (two frameworks manipulating the DOM don’t play nice together). 
 
Just my thoughts, it’s not written in stone :D

Migrating ASP.NET MVC to WebApi with no breaking changes

Recently I’ve had the pleasure to upgrade our REST interface at work from Asp.Net MVC3 to WebApi so I thought a lessons learned or “watch out for this” blog post was suitable, especially since I managed to do it without the need to bump any version number on our server i.e. no breaking changes.

I think there are others out there that have been using the MVC framework as a pure REST interface with no front end, i.e. dropping the V in MVC, before webapi was available.

Filters

First of all webapi is all about registering filters and message handlers and letting requests be filtered through them. A filter can either be registered globally, per controller or per action which imo already is more flexible than MVC.

public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        ...
        GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHandler());
        GlobalConfiguration.Configuration.MessageHandlers.Add(new MethodOverrideHandler());
        GlobalConfiguration.Configuration.Formatters.Insert(0, new TypedXmlMediaTypeFormatter ...);
        GlobalConfiguration.Configuration.Formatters.Insert(0, new TypedJsonMediaTypeFormatter ...);
        ...
    }
}

 

Metod override header

Webapi doesn’t accept the X-HTTP-Method-Override header by default, in our installations we often see that the PUT, DELETE and HEAD verbs are blocked. So I wrote the following message handler which I register in Application_Start.

public class MethodOverrideHandler : DelegatingHandler
{
    private const string Header = "X-HTTP-Method-Override";
    private readonly string[] methods = { "DELETE", "HEAD", "PUT" };

    protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Method == HttpMethod.Post && request.Headers.Contains(Header))
        {
            var method = request.Headers.GetValues(Header).FirstOrDefault();
            if (method != null && methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
            {
                request.Method = new HttpMethod(method);
            }
        }

        return base.SendAsync(request, cancellationToken);
    }
}

 

Exception handling filter

In our controllers we throw HttpResponseExceptions when a resource isn’t found or if the request is bad for instance, this is quite neat when you want to short-circuit the request processing pipeline and return a http error status code to the user. The thing that caught me off guard is that when throwing from a controller action the exception filter is not run, but when throwing from a filter the handler is run. After some head scratching I found a discussion thread on codeplex where it’s explained that this is intentional, so do not throw exceptions in your filters.

We have a filter which looks at the clients accept header to determine if our versions (server/client) are compatible, this was previously checked in our base controller but with webapi it felt like an obvious filtering situation and we threw Not Acceptable if we weren’t compatible. This needed to be re-written to just setting the response on the action context and not calling on the base classes OnActionExecuting which imo isn’t as clean design.

public class VersioningFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {            
        var acceptHeaderContents = ...;
        if (string.IsNullOrWhiteSpace(acceptHeaderContents))
        {                
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "No accept header provided");
        }
        else if (!IsCompatibleRequestVersion(acceptHeaderContents))
        {             
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotAcceptable, "Incompatible client version");
        }
        else
        {
            base.OnActionExecuting(actionContext);
        }
    }
}

 

Request body model binding and query params

In MVC the default model binder mapped x-www-form-encoded parameters to parameters on the action if the name and type matched, this is not the case with webapi. Prepare yourself to create classes and mark the parameters on your controller with the FromBody attribute even if you only want to pass in a simple integer that is not a part of the URI. Furthermore to get hold of the query params provided in the URL you’ll need to pass in the request URI to the static helper method ParseQueryString on the HttpUtility class. It’s exhausting but it will work and it still doesn’t break any existing implementation.

[HttpGet]
public HttpResponseMessage Foo([FromBody]MyModel bar)
{
    var queryParams = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    string q = queryParams["q"];
    ...
}

 

Posting Files

There are plenty of examples out there on how to post a file with MVC or WebApi so I’m not going to cover that. The main difference here is that the MultipartFormDataStreamProvider needs a root path on the server that specifies where to save the file. We didn’t need to do this in MVC, we could simply get the filename from the HttpPostedFiledBase class. I haven’t found a way to just keep the file in-memory until the controller is done. I ended up with a couple of more lines of code where I create the attachments directory if it doesn’t exist, save the file and then delete it once we’ve sent the byte data to our services.

[ActionName("Index"), HttpPost]
public async Task<HttpResponseMessage> CreateAttachment(...)
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    } 

    string attachmentsDirectoryPath = HttpContext.Current.Server.MapPath("~/SomeDir/");
    if (!Directory.Exists(attachmentsDirectoryPath))
    {
        Directory.CreateDirectory(attachmentsDirectoryPath);
    }

    var provider = new MultipartFormDataStreamProvider(attachmentsDirectoryPath);
    var result = await Request.Content.ReadAsMultipartAsync(provider);
    if (result.FileData.Count < 1)
    {
        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }
    
    var fileData = result.FileData.First();
    string filename = fileData.Headers.ContentDisposition.FileName;
    
    Do stuff ...

    File.Delete(fileData.LocalFileName);    
    return Request.CreateResponse(HttpStatusCode.Created, ...);
}

 

Beaking change in serialization/deserialization JavaScriptSerializer -> Newtonsoft.Json

So WebApi is shipped with the Newtonsoft.Json serializer, there are probably more differences than I noticed but date time types are serialized differently with Newtonsoft. To be sure that we didn’t break any existing implementations I implemented my own formatter which wrapped the JavaScriptSerializer and inserted it first in my formatters configuration. It is really easy to implement custom formatters, all you need to do is inherit MediaTypeFormatter.

public class TypedJsonMediaTypeFormatter : MediaTypeFormatter
{        
    private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
    
    public TypedJsonMediaTypeFormatter(MediaTypeHeaderValue mediaType)
    {        
        SupportedMediaTypes.Clear();
        SupportedMediaTypes.Add(mediaType);
    }

    ...

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
    {
        var task = Task<object>.Factory.StartNew(() =>
        {
            var sr = new StreamReader(readStream);
            var jreader = new JsonTextReader(sr);
            object val = Serializer.Deserialize(jreader.Value.ToString(), type);
            return val;
        });

        return task;
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
    {
        var task = Task.Factory.StartNew(() =>
        {
            string json = Serializer.Serialize(value);
            byte[] buf = System.Text.Encoding.Default.GetBytes(json);
            writeStream.Write(buf, 0, buf.Length);
            writeStream.Flush();
        });

        return task;
    }
}

 

MediaFormatters Content-Type header

Any real world REST interface needs to have a custom content type format and by default the xml and json formatter always returns application/xml respectively appliation/json. This is not good enough, I suggest that you create custom implementations of JsonMediaTypeFormatter and XmlMediaTypeFormatter and insert them first in your formatters configuration. In your custom formatter just add your media type that includes the vendor and version to the SupportedMediaTypes collection. In our case we also append the server minor version to content type as a parameter, the easiest way to do that is by overriding the SetDefaultContentHeaders method and append whichever parameter you want to the header content-type header.

public class TypedXmlMediaTypeFormatter : XmlMediaTypeFormatter
{
    private readonly int minorApiVersion;

    public TypedXmlMediaTypeFormatter(MediaTypeHeaderValue mediaType, int minorApiVersion)
    {
        this.minorApiVersion = minorApiVersion;
        SupportedMediaTypes.Clear();
        SupportedMediaTypes.Add(mediaType);
    }

    ...

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType.Parameters.Add(new NameValueHeaderValue("minor", minorApiVersion.ToString(CultureInfo.InvariantCulture)));
    }
}

 

I think that covers it all, good luck migrating your REST api!

I might cover upgrading from WIF 3.5 (Microsoft.IdentityModel) to WIF 4.5 in my next post, or thinktectures startersts to identity server v2. Take a wild guess what I’ve been busy with at work! ;-)

Performance measurement ASP.NET MVC vs. WebAPI

I’ve been playing around with WebAPI for a couple of days now and I’m quite pleased with most of it so far. At work we have a stripped down a MVC3 site (threw away the M and the V) for ur public REST interface. Except for the ugly ActionResults in the controllers we are satisfied with it so far. I’ve read some articles on how the web api pipeline is supposed to be more optimized so I thought I’d put it up for a test before trying to sell in the platform upgrade to our product owners, also it would result in our first major version bump so we need to be sure that we can benefit from it and not just do it for the sake of fun (for me :-)).

The server side is a simple controller with 4 actions, 1 get, 1 post, 1 put and 1 delete method that only returns a status code, no I/O or business logic we just want to compare the pipelines. The test will run a five parallel threads executing 100 000 requests all together. The MVC site is hosted on a IIS 8 Express server and the WebAPI is both self hosted and hosted on a IIS8 Express server. The test was performed on my developer laptop running on Intel Core i7 CPU @ 2.67 (dual core with two threads on each CPU), 8GB RAM and 64 bit Win7 operating system.

  Avg. request time (ms) Total run time (s) Requests per second
MVC (IIS) 0.42 41.83 2391
WebAPI (IIS) 0.35 35.06 2852
WebAPI (Self Hosted) 0.12 11.67 8567

 

The results don’t say much since the average request time is very fast in all three cases but a relative comparison shows that MVC vs. WebAPI on IIS is ~20% and the self hosted console application is a whole ~260% faster. Although this pure pipeline time will be negligible when adding business logic with I/O operations or even a single WCF call (~50ms perhaps?).

There’s a whole lot more I could write about asp.net webapi but I’ll save it for future blog posts and leave you with the performance measure for now. 

The code for the test is available for download here, please don’t contact me about translating it to VB ;-)

Peace!

Building real-time web app with SignalR

We just recently had lab days at work which for me basically means that I can play around with some new tech to keep myself up to date. Anywho, one of the things I tried out was SignalR which is a .net library for building real-time, multi-user interactive web applications.

To goal was to build a simple chat, textbook example, shouldn’t be any fuzz, right? I started out with an asp.net mvc 3 empty project and installed the EntityFramework, SignalR and knockoutjs nuget packages. Lately I’ve been using knockoutjs pretty much in all my web projects, I’m a big fan!

PM> Install-Package EntityFramework
PM> Install-Package knockoutjs
PM> Install-Package SignalR

I’m not a big fan of entity framework code first but it was enough for my throw-it-away-when-you’re-done requirements. The basic idea is to just create POCOs and decorate the properties with attributes and the db will be generated for you.

The only entity I want to store is a chat message:

public class Message
{
    [Key]
    public int MessageId { get; set; }

    [Required, MaxLength(200)]
    public string Text { get; set; }
}

and the actual database context as

public class DatabaseContext : DbContext
{
    public DbSet&lt;Message&gt; Messages { get; set; }
}

keeping it really simple, no relations at all. And let’s not forget to register the initializer in Application_Start.

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DatabaseContext>());

Now to the fun part, SignalR. We simply create a Hub that runs on the server that will be able to invoke methods on our clients.

public class Messages : Hub
{
    public void GetAll() { ... }
    public bool Add(Message newMessage) { ... Clients.messageAdded(message); ... }
}

and on our page we only need to 1) create a proxy on the fly, 2) declare a function on the hub so the server can invoke it, 3) call on the add method on the server.

$(function () {
    // proxy created
    this.hub = $.connection.messages;

    // method invoked by the server when a message is added
    this.hub.messageAdded = function (m) { ... };

    // how we send a message to the server
    this.sendMessage = function () { ... this.hub.add(m); ... };
});

The server-side code is telling all the clients to call the messageAdded() JavaScript function. Mind blowing? We are actually calling the client back from the server by sending the name of the client method to call from the server via our connection. SignalR handles all the connection stuff on both client and server and makes sure the channel stays open and alive.

Screenshot of desktop browser and windows phone emulator browser:

signalr_wp_browser

 

Download the code (793,9KB) for full example.

 

ASP.NET MVC 4 Mobile Features

I read about mvc 4 and decided to try out some of the new cool mobile features, so I went ahead and installed it, it installs side-by-side with mvc 3 so that’s nice. It comes with a new mobile application project template that uses jquery mobile which looks pretty good but since I want to build a web application for both desktop and mobile devices I’m going to start off from the internet application project template.

The default template uses CSS media queries which is an extension to CSS for media types, it allows you to override the default css rules for different agents. CSS rules defined inside

@media only screen and (max-width: 850px) {

will be applied if the browser window is 850 pixels wide or less. That combined with the viewport meta tag

<meta name="viewport" content="width=device-width">

makes the default project template render pretty nice in both desktop and mobile browsers as seen below.

aspnetmvc4_mobile_responsive

So what should I do if that isn’t enough? I want to completely customize the views for mobile agents but still use the same controllers. This is easily done! MVC4 introduces a mechanism to override views, layouts and partial views by naming conventions. For instance to get a mobile specific index page I simply add Index.Mobile.cshtml, same goes for the layout i.e. Shared\_Layout.Mobile.cshtml.

Having that said, let’s customize the mobile views, for that I’d like to use the jQuery mobile library that works on all the major mobile browsers. Installing the jQuery.Mobile.MVC NuGet package will get us on our way.

PM> Install-Package jQuery.Mobile.MVC

The package will setup the scripts and reference them and create a _Layout.Mobile.cshtml which links in the jquery mobile css, I needed to manually change the referenced jQuery version in _Layout.cshtml from 1.6.3 (default) to 1.6.4. A neat detail with this package is that a view switcher controller is added which enables us to easily switch between the desktop and mobile version.

I created the corresponding mobile views in /Home and threw in the following code into _Layout.Mobile.cshtml

<ul data-role="listview"&gt;
	<li data-role="list-divider">Navigation</li>
	<li>@Html.ActionLink("Home", "Index", "Home")</li>
	<li>@Html.ActionLink("About", "About", "Home")</li>
	<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

and simple as that I now had a mobile customized site.

aspnetmvc4_mobile_custom_mobile

Doesn’t get much easier than that!

Code available here (4,4MB), haven’t done much though! ;-)

/A