Creating a RESTful Web Service Using ASP.Net MVC Part 23 – Bug Fixes and Area Support

June 6, 2010 00:04 by admin

Joel Feaster emailed to say he was having trouble with the Accept header handling of the web service. When he used jQuery’s getJSON method it would use the following Accept header:

application/json, text/javascript, */*

You’ll notice there are no q parameters in that header, so according to the HTTP 1.1 specification, they should all be treated as having a q value of 1. However, the specification does not dictate which format should take precedence when all acceptable formats have the same q value. But looking at that header and knowing it comes from a method named getJSON, you might hope the web service would pick application/json.

Accept Header Processing

Deep within the web service, the method GetAcceptHeaderContentTypes() will take an Accept header and turn it into a list of ContentType objects ordered by the clients preference. However, it uses the List<T>.Sort method, the help for which states:

This method uses Array.Sort, which uses the QuickSort algorithm. This implementation performs an unstable sort; that is, if two elements are equal, their order might not be preserved. In contrast, a stable sort preserves the order of elements that are equal.

So, the Sort method could (and in Joel’s case does) jumble up the formats which have the same q value. Whilst this is not wrong according to the specification, some clients are indicating their preference by the Accept header ordering. Therefore, I decided to look at improving the GetAcceptHeaderContentTypes to preserve the original order if no other preference is given.

I couldn’t (at least not quickly) find a stable sort algorithm within the .Net Framework. I could have copied one from the web or written one myself… but I decided to use a simpler approach. Instead of a list of ContentType objects, I created an object to wrap each ContentType object along with its original position. I then changed the implementation of IComparer so that if there is nothing else to choose between two formats, the original position would be used.

So, surely that would fix Joel’s problem. Well, not quite. Whilst looking again at the IComparer implementation, I realised there were a few more issues with it. I worked on it until all the samples provided in the HTTP 1.1 specification were being interpreted correctly.

Areas Support

I’ve recently been working on a large web service and wanted to make use of the new Areas feature that was included with ASP.Net MVC 2. So, I’ve also extended the VirtualPathProviderXsltEngine class (which is used to look up the XSLT view files) to understand the concept of Areas. I also added a set extension methods to allow the Areas registration to take into account Restful routes. Now you can use these in your AreaRegistration classes. For example:

public class XYZAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "XYZ";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRestfulRoute(
            "Xyz_default",
            "Xyz/{controller}",
            new { controller = "Xyz", action = "List" }
        );
    }
}

The latest version of the code is available here: RESTfulMVCWebService23.zip (127.01 kb)


Comments (7) -

June 14. 2010 22:17

piers

John White - please get in touch again, you provided a bad email address!

piers

July 28. 2010 16:05

Stephen

Any plans to add security to your framework.  Specifically something along the lines of how Amazon does AWS request authentication?

docs.amazonwebservices.com/.../...tionArticle.html

Stephen

July 28. 2010 21:28

Piers Lawson

I don't have plans to at the moment... but I have previously successfully combined the framework with the custom Basic Authentication framework provided on leastprivilege.com and also available on codeplex: http://custombasicauth.codeplex.com/

Piers Lawson

July 30. 2010 11:02

Stephen

I will have a look at that, thanks.  \

2 Questions:
1)  Would you mind if I use your project as a base for a public REST API for a large South African Financial institution?
2)If I use your project as a base and add AWS style security would you be interested in me sharing my additions with you?

Thanks,
Stephen

Stephen

July 30. 2010 21:58

Piers Lawson

@Stephen - I'm very happy for you to use the framework however you want... and yes, if you put together a security model I'll have a look and see how I could include it.

Piers Lawson

March 2. 2011 16:35

builders manchester


I like the spam comment. Ive clicked your adsense ads so hope that couple of dollers/pounds have contributed in helping me keep the spammy comment

<a href="www.buildersinmanchester.org">builders manchester</a>

builders manchester

March 3. 2011 12:32

handyman manchester

Hi piers i've given your adsense a couple of clicks, cheers

handyman manchester

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading