Thoughts on developing resilient Ajax code (Part 2 – ASP.net MVC)

In my last post we looked at different methods to indicate a call to a service that would return JSON was unsuccessful.

The conclusion was that we really want to be setting the HTTP status code of the response to indicate a request was unsuccessful.

In this post we will look at some possibilities for wrapping this logic up in ASP.net MVC controller methods (and there are many).

We want a way of:

  • Setting the status code of the response
  • Including in the response our errors formatted as JSON
  • Something that’s easy to reuse and maintain

The most obvious (and least reusable) option is probably something like:

Response.StatusCode = (int) HttpStatusCode.InternalServerError;
return Json(new { data = "bad error" });

We could also use the HttpStatusCodeResult class however this only allows us to set the description of the error status code rather than the body of the response:

return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, "bad error");

We could remedy this with something like this:

Response.Write("bad error");
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, "bad error");

But we also want to format our response as JSON and set the return content-type to application/json so would then have to do something like this:

var errors = new List<string>() {"Bad error", "Another bad error"};
var serializer = new JavaScriptSerializer();
Response.ContentType = "application/json";
Response.Write(serializer.Serialize(errors));
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, "bad error");

Yuck!

This is getting a bit messy & we want something easy to use, maintain & test.

ASP.net MVC is very flexible and we have a number of different ways to do this but I reckon inheriting from JsonResult works pretty well for our purposes:

public class JsonErrorResult : JsonResult
{

private readonly HttpStatusCode _statusCode;

public JsonErrorResult(HttpStatusCode statusCode)
{

_statusCode = statusCode;

}

public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = (int)_statusCode;
base.ExecuteResult(context);
}

}

With this new type of ActionResult we get all the functionality of JsonResult and can also set the status code of the response easily:

var errors = new List<string>() {"Bad error", "Another bad error"};
return new JsonErrorResult(HttpStatusCode.InternalServerError) {Data = errors};

If we use browser tools we can see the Http status code was set correctly to 500, the content type is application/json and the response body contains our json encoded messages for later display:

1-12-2012 1-53-19 PM

Another option is to create a custom Action filter (this can be shortened by returning a JsonErrorResult as above):

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class HandleErrorAsJsonResponseAttribute : ActionFilterAttribute, IExceptionFilter
{

public void OnException(ExceptionContext filterContext)
{

if (filterContext.HttpContext.Request.IsAjaxRequest())
{

filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { errorMessage = filterContext.Exception.Message}
};

}

}
}

This is very easy to apply (and can be done so at method, controller and even application level):

[HandleErrorAsJsonResponse]
public ActionResult ThrowError()
{
throw new Exception("bad exception");
}

I think these serve my purposes pretty well but if anyone’s got better ways of doing this I would love to hear them 🙂

Next up what’s jQuery actually doing in $.ajax

Introducing .net 4.5 book

About two years ago, I wrote a book (Introducing .NET 4.0 with Visual Studio 2010). This was an ambitious (and time-consuming!) project where I set out to provide a high-level overview of all the major changes across the framework from ASP.NET to WCF.

When writing it, I tried to keep in mind the following objectives:

  • Give the reader an introduction to new technologies
  • Show how to perform the basics that any developer would want to know
  • Produce examples that are as simple as possible but still demonstrate the concept
  • Don’t get too bogged down in detail so the book can still be easily read

The book was well received (although not quite as well as one involving wizarding schoolchildren, lame-ass vampires or perhaps more recently a very bad (so I hear!) erotic novel). Thus, despite promising myself that I wouldn’t write another book in a hurry, I find myself writing about the changes in .NET 4.5 and Visual Studio 2012.

This book has the same aims as the previous book. However, I have also made a few changes to address what I felt were weaknesses of the first text.

Given the breadth of the subject matter, it was impossible to cover all the subject areas in as much detail as each topic deserved. Some chapters of the first book were much stronger and more in-depth than others. Sometimes the level of depth reflected the information available, but my own areas of interest and knowledge also influenced how thoroughly I covered any given topic.

So, this time—with the added bonus of not having to do quite as much work!—I have taken some friends and colleagues along for the ride.

It is my pleasure to introduce you to my fellow authors, Mahesh Krishnan and William Tulloch. I had the (dubious?) pleasure to work with Mahesh and William at the Australia-based consultancy Readify. Mahesh specializes in the areas of Azure, WCF, and Silverlight, and he is the author of Microsoft Silverlight 4 for Dummies. William specializes in WCF and WIF.

Im pretty happy with the content of the book and think we give a good intro to the various new features available. If you want a really deep look at the various changes or a reference to keep on your shelf then this probably isnt the book for you (I really like Joseph Albahari’s C#5 in a nutshell). If however you want a light hearted, easy to read introduction and can put up with my terrible sense of humour then I think you will enjoy it and it will get you up to speed quickly.

As is always the case <sigh> after going to print a few issues are found (I am keeping track of these at http://www.simpleisbest.co.uk/what-we-screwed-up) our apologies for any future typo’s etc that will undoubtedly be found.

Thank you to everyone that assisted with putting the book together, contributed their experiences or advice or explained something in more detail to us – we couldn’t have done it without you.

Ill also be donating 50% of my earning from this book to Cancer Council Australia.

You can order the book from Amazon via this link.

Alex

retryAjax – retry jQuery ajax requests

I wanted to write a little wrapper for jQuery’s Ajax function that would retry a request in the event of a transient failure. This could be quite a common scenario for a mobile optimized website where a users mobile device moves out of signal area briefly. I also wanted to add the ability to increase the time between request attempts with a backoff function so as not to waste requests.

I played around a bit with proxying jQuery’s core Ajax function in the sameway jquery-mockajax  does. I also discovered some other interesting options using jQuery prefilters which I wasnt aware of existed but will certainly be taking a deeper look into.

Anyway I settled on adding another method called ajaxWithRetries.

It’s my first stab at this on a lazy sunday arvo so its likely to be quite buggy (current retry count is not specific to an individual function for example) & I havent tested it on various browsers so use at your own risk 🙂

Its up on github at https://github.com/alexmackey/retryajax

 

Hello Kiandra IT

After 2 years and about 5 months I have decided to leave Readify to work for the Melbourne consultancy Kiandra IT (http://kiandra.com.au/) and in just over a weeks’ time will have to do some work again after a few weeks off 🙂

Readify has been a great experience and I hope I’ll still keep in touch with many of the staff.

My initial impressions of Kiandra have been excellent from the very welcoming and enthusiastic staff at my interview to a nice bottle of wine & company t-shirt couriered with paperwork on acceptance of offer to their recent wins of a number of industry awards.

I’m really looking forward to having a desk again and getting stuck into some longer term projects. I have to admit I am a little concerned to be working with Mr Lars Klint (http://klint.co/) but am hoping the other excellent staff will offset his inane ramblings & madness 😉

Don’t worry this move doesn’t mean I won’t be any less involved with the user group and Melbourne dev community 🙂 

As I write this Kiandra is currently looking to fill a number of roles in testing, UX and Business Analysis so why not take a look and join us at: http://kiandra.com.au/join-us/

Theory of constraints – or why you may be wasting your time

A few months ago I attended an excellent session at the LAST conference given by a guy called James Ross on Theory of Constraints (the session abstracts here: http://lanyrd.com/2012/last-conf/swycf/).

Theory of Constraints (TOC) was developed by a guy called Eliyahu Goldratt who sets out the idea in a book called the Goal (http://www.amazon.com/The-Goal-Process-Ongoing-Improvement/dp/0884271951/ref=sr_1_1?ie=UTF8&qid=1347002336&sr=8-1&keywords=the+goal).

It’s an unusual book in that the idea is presented by telling the story of a plant manager of a failing manufacturing plant. The main character is given 3 months by his bosses to turn the plant around and the book takes the reader through how he achieves this and the problems he encounters along the way.

The book is well worth a read (if only for its unique fiction style!) but the short version is that a system is limited by its slowest part.

An example – well let’s say we have a very simple system made up of 3 processes (imaginatively called A,B,C) that can each produce an arbitrary number of widgets (shown in brackets next to the process name) in one equally arbitrary time segment. Each process depends on the output of the predecessor:

Process A (5) -> Process -> B (5) -> Process C (2)

What’s the maximum output such a system can have?

Well despite A & B being able to produce 5 widgets the maximum output this system can ever have is 2 as Process C can only ever produce 2 widgets.

This means that if you are putting a lot of effort into improving Process A you are wasting your time as the maximal output will only ever be 2. If we want to improve the output of the system we should concentrate our efforts on Process C.

Of course a real system will also have fluctuations e.g. maybe there is a minor cockup, someone is sick so a more realistic output maybe more like:

Process A (3-5) -> Process -> B (3-5) -> Process C (1-2)

In our example we want to make sure that Process C is running as fast as possible otherwise everything slows down. Thus we might employee additional staff in Process C as a buffer as even if they don’t do anything 50% of the time we don’t want this bit of the system slowing down.

At first this all seems a pretty common sense idea but the outcome of this is that if you are trying to improve something that isn’t a bottleneck in the system any improvements you do get will be very limited (although I guess improvements could have an influence on other areas e.g. people may pick up ideas etc).

Even through the books examples are focussed on manufacturing it’s certainly not just applicable to factory settings. For example the book has an example of kids going on a hike where the unfit tubby kid limits the speed of the others (and im ignoring for now the best way to optimize flow in this scenario).

I believe this example has implications for us as developers and consultants as if we are trying to improve a non-bottleneck part of a system we really aren’t going to make much if any of a difference.

Instead we should be looking at what we can do to alleviate any bottle necks. Maybe this can be done by restructuring the process, hiring more people (even if they end up doing nothing half the time as the bottle neck process is constraining your entire output) or even outsourcing the work.

In software development maybe the bottleneck in your environment is getting requirements, maybe its producing a build, maybe its the testing department.

So in conclusion its important to identify potential bottle necks within your system and focus efforts in these areas.

Speaking at Web Directions What Do You Know evening

I’ll be speaking at the Web Directions What Do You Know evening on Thur Feb 16th on the Navigation Timing API (http://whatdoyouknow.webdirections.org/melbourne).

I am looking forward to speaking at this event as the format is a little different from what I am used to consisting of several short 5 minute presentations from 11 presenters.

The Melbourne event is sold out now (hey Navigation Timing API talks are pretty popular he he ) but there are still spaces left in Sydney, Brisbane & Perth events as of 6th Feb.

 

CSS Profiler

Opera has a prototype CSS profiler available that looks interesting that can shed some light on expensive selectors that you may want to optimize.

To use the profiler:

  • First make sure you have downloaded the latest version of Opera
  • Enter opera:config#developerTools in the address bar to open the configuration section
  • Amend the developer tools url to https://dragonfly.opera.com/app/stp-1/profiler/

To bring the profiler up access a page, right click select element (choose anything). Click the red record button to start the profile and refresh the page. Click the record button again to stop the trace.

Opera will then give you a break down of where time was spent rendering. If you click individual style calculation (the orange blocks or the style recalculation section you will receive a detailed breakdown).

Opera CSS Profiler

It’s early days for the profiler but looks really interesting.

Mobile Safari Crashing

We recently encountered an issue on a jQuery Mobile site where  Mobile Safari on an Ipod touch devices mobile safari would crash when accessing certain pages.

It was impossible to recreate the crashes on a desktop machine or Iphone device. Hmm what to do?

The first step is to try and get some info for what caused the crash. You can retrieve the reason for a crash on an i device by syncing it with Itunes.

On my windows machine crash reports are stored at the following location (yours will obviously differ depending on user and device name):

C:\Users\alex\AppData\Roaming\Apple Computer\Logs\CrashReporter\MobileDevice\alexs iPhone4

Crash reports for Mobile Safari have a file name similar to the following:

MobileSafari_2011-10-1-184202_alexs-iPhone4.crash

If you open up this file in notepad you may (or may just get a cryptic message) about what caused the crash.

Within this file was a report of low memory condition. We initially reviewed the pages that were crashing the ipod touch devices and found they had many DOM elements on the page (the client had asked us to replicate an existing iphone application exactly – let’s ignore whether this is a good idea for the time being..). The developer had also attached a click event to each individual element (far better to let the event bubble up the containing element). In addition to the large number of elements jQuery mobile would add its own styling/elements further compounding the problem.

The solution was to modify the event handler to capture bubbled up events and reduce the number of DOM elements. The pages then would not crash on the ipod touch device. It appears that i devices have around 10mb of memory that is shared across tabs. Due to jQuery mobile keeping pages around in the DOM you could run into this sort of issue fairly quickly so its vital to be sensible with your event binding and HTML coding. It’s also worth noting that we couldn’t get iPhone devices to crash so they probably have more memory than an iPod touch (Apple documentation is woefully inadequate regarding this..)

2012 Goals

I read a number of blog posts where individuals detailed their goals and what they were looking forward to over the coming year.

I like the idea of publicly stating your goals as believe that it can help qualify these in your own mind and make you more committed to achieving them.

I think the career highlights for me last year were:

  • Speaking at Remix and TechEd
  • Going to MVP conference – although I dont feel I learnt that much from this I enjoyed travelling to Seattle, meeting a few people and seeing the Microsoft Campus
  • Udi Dahan’s architecture course opened my mind to some new ideas
  • An interesting course on Web Accessibility from Derek Featherstone
  • Winning an internal company award for company/community contribution that enables me to go to a conference of my choice
  • Getting another book contract from Apress to write on .net 4.5 and Visual Studio 11
  • An interesting mobile site project that has just gone live

So my goals for 2012 are the following:

  • Understand WCF better – I dont like WCF as it seems way over complex but I should probably make more of an effort as its getting pretty hard to avoid..
  • Complete book Apress book on .net 4.5 Visual Studio 11 that I am currently working on (funny how you think you will never do this kind of thing again)
  • Create some sort of open source/fun project to keep skills up – enterprise development can be a little depressing at times so think it needs to be some kind of game or something.. 🙂
  • More blogging and talks – been a bit lax on this and have come across several useful tips/tricks/gotchas that I want to document
  • Run DDD Melbourne again in June/July

On a personal/non technical level I want to do the following:

  • Ensure better separation of work/personal life – I got pretty bad at this towards the end of last year and am not going down this route again!
  • Found a weight training club with a very experienced trainer – keen to advance in this area as hit a plateau through my own training – the last two sessions have completely smashed me!
  • Complete cert 4 personal trainer (cert 3 completed last year)

I am particularly looking forward to the following:

  • Visiting UK for 3 weeks
  • NDC conference