ASP.NET Web API: Fun with verbs

21 בפברואר 2012

one comment

For those of you who do follow me on twitter (shame on you), last Thursday’s announcement about the reincarnation of the WCF Web API as the ASP.NET Web API could not come in worst timing. As I was scheduled to deliver a 3 hours session in Microsoft for an audience of WCF developers entitled REST via the WCF Web API. Since yours truly is not one of those speakers that is willing to talk about last weeks technology, I have spent most of the weekend rewriting my demos and rebuilding the session (the demos can be found here).

Now the the storm have passed, I had some time to go back and revisit my new found love. Before we begin I have one confession to make: last time I actually wrote ASP code this is what it was called, ASP, and .NET was starting its first beta. I guess what I am going thru right now is going to be a common pain for WCF developers who developed HTTP services in the past few year.

So for my session I built a fantasy football site called my footy. my first and most basic functionality was to create my  services controller (formally known as service) using the ASP.NET MVC 4 template for Web API. the basic template creates a project built more or less like most MVC projects (as far as a WCF guy like me can tell) with minor differences. My first stop was to create the players controller that looked more or less like this:

public class PlayersController : ApiController
{

    // GET /players/neymar
    public Player Get(string name)
    {
        // method implementation
    }

    // POST /players
    public HttpResponseMessage<Player> Post(Player player)
    {
        // method implementation
    }

    // DELETE /players/neymar
    public void Delete(string name)
    {
        // method implementation
    }
}

As you can see I have different methods (that’s C# methods) for different HTTP verbs. the verbs are mapped to the methods by convention (apparently this is called convention over configuration). This convention will map the verb to any method who's name starts with the verb so I can have even more meaningful method names. As you can see my Post and Delete methods accept a name parameter that in the old days (last week) we used to map using a Uri template in our WebGet or WebInvoke attributes. Now in the days of ASP.NET web API this is mapped as part of the routing registration in the Global.asax like this:

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "{controller}/{name}",
    defaults: new { name = RouteParameter.Optional }
);

This tells ASP.NET to use the above template when accessing the application, first parameter is the name of the controller second one is a parameter called name. Since I am using IIS to run my application, I needed to allow Delete which is blocked by default by WebDAV (and thanks to Sebastian Pederiva for his IIS support) so I added the following section to my default web site’s Web.Config:

<system.webServer>
  <modules>
    <remove name="WebDAVModule" />
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>

Works like a charm. The next functionality I had for my players service was to add a transfer functionality, so my users could trade players. I have added the Transfer method that looks like this:

public HttpResponseMessage<Player> Transfer(Player player, string teamName)
{
    // method implementation
}

So now I had to tweak my routing to support this, so I’ve added a second HTTP route mapping like this:

routes.MapHttpRoute(
    name: "TransferApi",
    routeTemplate: "{controller}/{action}/{teamName}",
    defaults: new { name = RouteParameter.Optional }
);

Now I could have used HTTP Post to access my method using the Uri template: “players/transfer/{teamName}”. But wait, this is not all. I could now access my method using HTTP Get. This is apparently a usual behavior for ASP.NET MVC and we can solve this by adding the HttpPost attribute:

[HttpPost]
public HttpResponseMessage<Player> Transfer(Player player, string teamName)
{
    // method implementation
}

That’s better, but we are not nearly done. One of the side effects of my second route mapping is that now my Get, Post and Delete methods are also mapped as action (beside being mapped to HTTP verbs) so I can now get the representation of a player both by using http://localhost/players/neymar and http://localhost/players/get/neymar as an address. While I can live with two addresses exposing the same resource the issue is a bit trickier with my Delete method that is now accessible either by using the verb Delete using the http://localhost/players/neymar Uri and using the verb Get and the http://localhost/players/delete/neymar Uri. Using Get to delete resources is just bad HTTP, if for no other reason than due to fact HTTP assumes get is both safe and idempotent (you can read more about safe and idempotent verbs here)  so I added the HttpDelete attribute to make sure my service is consumed the way I planned it to be consumed:

[HttpDelete]
public void Delete(string name)
{
    // method implementation
}

That’s better Smile

I guess if you are coming from ASP.NET MVC background most of what I showed here might seem trivial but for WCF developer there are a lot of things to notice here. With that said and done I do hope ASP.NET web API will encourage developers do write more HTTP services no matter what your background is.

Shout it

Add comment
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

תגי HTML מותרים: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

one comment

  1. http://monclerdiscountsshop.blogspot.com/26 באוקטובר 2013 ב 13:59

    moncler jackets from the brand name report from the ethnical marketing procedure, you use not one but two modalities, a single function connected with professionals should help firms earn the street Growth Course of action and type lots of model resources to supply interesting

    להגיב