February 2012 - Posts

ASP.NET Web API provides a very similar model to MVC for resolving dependencies using a service locator pattern. What you basically do is to provide the implementation of that service locator to return any of the requested dependencies, and that implementation is typically tied to a DI container. 

The service locator can be injected into the Web API runtime using the ServiceResolver entry in the global configuration object (GlobalConfiguration.Configuration.ServiceResolver), which basically supports different overloads.

public void SetResolver(IDependencyResolver resolver);
public void SetResolver(object commonServiceLocator);
public void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);

The first overload receives an instance of a IDependencyResolver implementation, which provides two methods for resolving one or multiple dependencies.

public interface IDependencyResolver
{
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

GetService should return null if the dependency can not resolved. GetServices should return an empty IEnumerable if the same thing happens.

The second overload uses reflection for invoking the same two methods, GetService and GetServices.

The third overload receives a set of Func delegates for doing the same thing.

Autofac already provides a very smooth integration with ASP.NET Web API through a set of assemblies available in the “Autofac ASP.NET MVC integration” nuget package. The bad news is that you can not use the DepedencyResolver implementation in that package as it is not compatible with the one required by ASP.NET Web API.

The AutofacDepedencyResolver class in that package implements System.Web.Mvc.IDependencyResolver, while ASP.NET Web API expects a System.Web.Http.Services.IDependencyResolver implementation. Nothing that we can not fix with  a simple few lines of code. We can reuse the existing implementation through the third overload that receives a set of delegates.

The following code snippet illustrates how you can register all dependencies in the Autofac container and use that for resolving all the Web API dependencies,

ContainerBuilder builder = new ContainerBuilder();
 
builder.RegisterType<ContactRepository>()
    .As<IContactRepository>()
    .InstancePerHttpRequest();
 
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 
IContainer container = builder.Build(); 
 
var resolver = new AutofacDependencyResolver(container);
 
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
    t => resolver.GetService(t),
    t => resolver.GetServices(t));

One the things you can do with Autofac is to set the lifetime of the dependencies instances to be equal to a http request lifetime by using the “InstancePerHttpRequest” method. I also created a simple extension method “RegisterApiControllers” to automatically register all the existing Api controllers in the the project into the DI container.

public static class RegistrationExtensions
{
    public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> RegisterApiControllers(this ContainerBuilder builder, params Assembly[] controllerAssemblies)
    {
        return
            from t in builder.RegisterAssemblyTypes(controllerAssemblies)
            where typeof(IHttpController).IsAssignableFrom(t) && t.Name.EndsWith("Controller")
            select t;
    }
}

Using the code above, you should be able to use a API controller that looks like this (The contact repository is injected as a depedency)

public class ContactController : ApiController
{
    IContactRepository repository;
 
    public ContactController(IContactRepository repository)
    {
        this.repository = repository;
    }
Posted by cibrax
Filed under: , ,

The Http status codes for reporting errors to clients can mainly be categorized on two groups, client errors and server errors. Any status code under 500 is considered an issue generated by something wrong on the request message sent by the client. For example, 404 for resource not found, 400 for bad request (some invalid data in the request message) or 403 for forbidden (an unauthorized operation) are some of the most well know client errors.  On the hand, any other code over 500 is considered as a problem on the server side such as 500 for internal server error or 503 for server unavailable. This kind of error means that something unexpected happened on the server side while processing the request but it is not the client fault.

It’s always a good practice when implementing a Web Api to use the correct http status codes for every situation. While it’s relatively easy to return a response with an specific status code in a controller action using the new HttpResponseMessage class, you might end up with a lot of repetitive code for handling all the possible exceptions in the different execution branches. All the dependencies for a controller like repositories or domain services are usually unaware of http details. For example, you might call a method in a repository that throws an exception when something is wrong, but it would be responsibility of the calling code in the Web Api controller to map that exception to an http status code.

As any cross cutting concern, exception handling can also be implemented in a centralized manner using a filter. This was the way it was implemented in MVC as well in the HandleErrorAttribute filter. ASP.NET Web API is not any different in that aspect, and you can also implement a custom filter for mapping an exception to an http status code.

This is how the filter implementation looks like,

public class ExceptionHandlerFilter : ExceptionFilterAttribute
{
    public ExceptionHandlerFilter()
    {
        this.Mappings = new Dictionary<Type, HttpStatusCode>();
        this.Mappings.Add(typeof(ArgumentNullException), HttpStatusCode.BadRequest);
        this.Mappings.Add(typeof(ArgumentException), HttpStatusCode.BadRequest);
    }
 
    public IDictionary<Type, HttpStatusCode> Mappings
    {
        get;
        private set;
    }
 
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Exception != null)
        {
            var exception = actionExecutedContext.Exception;
 
            if (actionExecutedContext.Exception is HttpException)
            {
                var httpException = (HttpException)exception;
                actionExecutedContext.Result = new HttpResponseMessage<Error>(
                    new Error { Message = exception.Message },
                    (HttpStatusCode)httpException.GetHttpCode());
            }
            else if (this.Mappings.ContainsKey(exception.GetType()))
            {
                var httpStatusCode = this.Mappings[exception.GetType()];
                actionExecutedContext.Result = new HttpResponseMessage<Error>(
                    new Error { Message = exception.Message }, httpStatusCode);
            }
            else
            {
                actionExecutedContext.Result = new HttpResponseMessage<Error>(
                    new Error { Message = exception.Message }, HttpStatusCode.InternalServerError);
            }
        }
    }
}

As you can see, the filter derives from a built-in class ExceptionFilterAttribute that provides a virtual method “OnException” for implementing our exception handling code. The ExceptionFilterAttribute does not nothing by default.

The exception handling logic in this implementation mainly address three different scenarios,

  1. If an HttpException was raised anywhere in the Web API controller code, the status code and message in that exception will be reused and set in the response message.
  2. If the exception type is associated to an specific status code using a custom mapping, that status code will be used. For example, the filter automatically maps the ArgumentNullException to a “Bad Request” status code. The developer can customize this mapping when the filter is registered.
  3. Any other exception not found in the mapping is considered a server error and the generic “InternalServerError” status code is used.

In all the cases, a model for representing the exception is set in the response message so the framework will take care of serializing that using the wire format expected by the client. The HttpResponseMessage also contains a string property “ReasonPhrase”, which could be used to sent the exception message back to the client. However, this property does not seem to be sent correctly when everything is hosted in IIS.

Let see a few different cases of how this filter works in action.

public Contact Get(int id)
{
    var contact = repository.Get(id);
    if (contact == null)
        throw new HttpException((int)HttpStatusCode.NotFound, "Contact not found");
 
    //Do stuff
 
    return contact;
}

A contact was not found, so a new HttpException with status code 404 is thrown in the controller action. This will be automatically mapped to a response message with 404 in the exception filter.

public void Delete(int id)
{
    bool canBeDeleted = this.repository.CanDelete(id);
 
    if (!canBeDeleted)
    {
        throw new NotAuthorizedException("The contact can not be deleted");
    }
 
    this.repository.Delete(id);
}

Assuming the client did have permissions to delete an existing contact, a custom exception “NotAuthorizedException” was thrown in the controller action. The default behavior in the filter will be to set an internal server error (500) in the response message. However, that logic can be overriding by adding a new mapping for that exception when the filter is registered.

var exceptionHandler = new ExceptionHandlerFilter();
 
exceptionHandler.Mappings.Add(typeof(NotAuthorizedException), HttpStatusCode.Forbidden);
 
GlobalConfiguration.Configuration.Filters.Add(exceptionHandler);

In that way, the client will receive a more meaningful status code representing a forbidden action.

Posted by cibrax | 8 comment(s)
Filed under: , ,

One of the nice things about having a single extensibility model between ASP.NET MVC and Web API is that you can get many of the great MVC features for free. Model binding and validation is one of them.

A simple action in Web API controller is typically associated to a Http verb and can optionally receive or return a model (or a message if you want to have better control over the http messaging details). For example, the following implementation illustrates a simple case for creating a contact when an Http POST is received,

public class ContactController : ApiController
{
    IContactRepository repository;
 
    public ContactController(IContactRepository repository)
    {
        this.repository = repository;
    }
 
    public HttpResponseMessage Post(Contact contact)
    {
        int id = this.repository.Create(contact);
 
        var response = new HttpResponseMessage(HttpStatusCode.Created);
        response.Headers.Location = new Uri("/api/Contact/" + id);
 
        return response;
    }
}

All the details for deserializing the request message into a Contact model is automatically handled by the Web API infrastructure. It actually uses the model binding feature found in MVC but it also adds content negotiation on top of it.

Content negotiation in Web API is implemented through formatters that know how to serialize/deserialize an specific payload associated to a content type (json or html for example) into a model.

As you probably know, the model binding infrastructure in MVC also allows validations on model classes decorated with data annotations. That means you can decorate your models with different validation attributes as it shown bellow,

public class Contact
{
    [Required]
    public string FullName { get; set; }
 
    [Email]
    public string Email { get; set; }
}

The model binding infrastructure will validate the model but Web API will not do anything with it by default. If you want to reject a message based on the result of the validations, you need to implement a custom filter in the current bits.

That can be done by extending an ActionFilterAttribute and overriding the OnActionExecuting method.

public class ValidationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            var errors = actionContext.ModelState
                .Where(e => e.Value.Errors.Count > 0)
                .Select(e => new Error
                {
                    Name = e.Key,
                    Message = e.Value.Errors.First().ErrorMessage
                }).ToArray();
 
            actionContext.Response = new HttpResponseMessage<Error[]>(errors, HttpStatusCode.BadRequest);
        }
    }
}

As you can see, the implementation is very simple. It only checks whether the model state is valid and return a list of validation errors. The execution pipeline will be automatically interrupted and response will be sent back to the client with the list of errors. I am also using a model for representing an error so Web API can send the expected wire format to the client application (If the client is expecting json, it will receive a list of errors formatted as json for example).

This validation attribute can be injecting into the execution pipeline by either decorating the api controller with it or by adding it to the global filters collection.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ValidationActionFilter());
}

Now, let’s see how this works in action with Fiddler. If we send a json message with an invalid email,

POST http://localhost:16913/api/Contact HTTP/1.1

Content-Type: application/json

Host: localhost:16913

Content-Length: 30

{"fullname":"re","email":"re"}

We will receive a response also formatted as json,

HTTP/1.1 400 Bad Request

Content-Type: application/json; charset=utf-8

[{"Message":"The Email field is not a valid e-mail address.","Name":"Email"}]

 

If we change the request message a little bit to expect xml as response

POST http://localhost:16913/api/Contact HTTP/1.1

Accept: text/xml

Content-Type: application/json

Host: localhost:16913

Content-Length: 31

{"fullname":"re","email":"foo"}

We will get a list of errors formatted as xml this time

HTTP/1.1 400 Bad Request

Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="utf-8"?><ArrayOfError xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Error><Name>Email</Name><Message>The Email field is not a valid e-mail address.</Message></Error></ArrayOfError>

Posted by cibrax | 5 comment(s)
Filed under: , ,

In case you did not see the latest news, what we used to know as WCF Web API was recently rebranded and included in ASP.NET MVC 4 as ASP.NET Web API. While both frameworks are similar in essence with focus on HTTP, the latter was primarily designed for building HTTP services that don’t typically require an user intervention. For example, some AJAX endpoints or a Web API for a mobile application. While you could use ASP.NET MVC for implementing those kind of services, that would require some extra work for implementing things right like content-negotiation, documentation, versioning, etc. What really matter is that both framework share many of the extensibility points like model binders, filters or routing to name a few.

If you don’t know what Backbone.js is, this quote from the main page in the framework website will give you some idea,

“Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface. “

You see, the framework will help you to organize your javascript code for the client side using an MVC pattern, and it will also provide an infrastructure for connecting your models with an existing Web API. (I wouldn’t use the term RESTful here as it usually implies your services adhere to all the tenets discussed in the Roy Fielding’s dissertation about REST). 

That means you should be able to connect the backbone.js models with your MVC Web API in a more natural way. As part of this post, I will use the “Todos” example included as part of the backbone.js code, but I will connect that to a Web API built using the new ASP.NET Web API framework. 

On the client side, a model is defined for representing a Todo item.

// Our basic **Todo** model has  `id`, `text`, `order`, and `done` attributes.
window.Todo = Backbone.Model.extend({
 
    idAttribute: 'Id',
 
    // The rest of model definition goes here
});

There is also a collection for representing the Todo list,

// The collection of todos is backed by *localStorage* instead of a remote
// server.
window.TodoList = Backbone.Collection.extend({
 
    // Reference to this collection's model.
    model: Todo,
 
    url: function () {
        return 'api/todos';
    },
 
    // The rest of the collection definition goes here
});

I modified the code for this collection to override the “url” setting. This new url will point to the route of our Web API controller. Backbone will try to synchronize all the changes in the models by sending http requests with the corresponding verb (GET, POST, PUT or DELETE) to that url.

Now, the interesting part is how we can define the Web API controller using the new ASP.NET Web Api framework.

public class TodosController : ApiController
{
    public IEnumerable<TodoItem> Get()
    {
        return TodoRepository.Items;
    }
 
    public IdModel Post(TodoItem item)
    {
        item.Id = Guid.NewGuid().ToString();
        
        TodoRepository.Items.Add(item);
 
        return new IdModel{ Id = item.Id };
    }
 
    public HttpResponseMessage Put(string id, TodoItem item)
    {
        var existingItem = TodoRepository.Items.FirstOrDefault(i => i.Id == id);
        if (existingItem == null)
        {
            return new HttpResponseMessage(HttpStatusCode.NotFound);
        }
 
        existingItem.Text = item.Text;
        existingItem.Done = item.Done;
 
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
 
    public void Delete(string id)
    {
        TodoRepository.Items.RemoveAll(i => i.Id == id);
    }
}

As you can see, the code for implementing the controller is very clean and neat. A name convention based on the Http Verbs can be used to route the requests to the right controller method. Therefore, I have different methods for retrieving the list of items (GET), creating a new item (POST), updating an existing item (PUT) or just delete it (DELETE)

A few things to comment about the code above,

  1. I haven’t specified the wire format anywhere in the code. The framework will be smart enough to do content negotiation based on the headers sent by the client side (In this case text/json).
  2. You can return any serializable class or a HttpResponseMessage if you want to have better control over the returned message (set the status code for example).
  3. The framework will take care of serialize or deserialize the message on the wire to the right model (TodoItem in this case)
  4. A hardcoded repository is being used, which is not a good practice at all, but you can easily inject any dependency into the controllers as you would do with the traditional ASP.NET MVC controllers.

Here is the class definition for the TodoItem model,

public class TodoItem : IdModel
{
    public int Order { get; set; }
    public string Text { get; set; }
    public bool Done { get; set; }
}

The IdModel is just a workaround for returning only an Id property to the client side when a new item is created. This is what backbone needs to associate an id to a new model. A more elegant solution would be to return an anonymous object with the id (such as new { Id = “xxx” }), but the default serializer for Json in the current bits (DataContractJsonSerializer) can not serialize them. Extending the built-in formatter to use a different serializer is something I am going to show in a different post.

public class IdModel
{
   public string Id { get; set; }
}

The default routing rule in the global.asax file is configured like this,

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

All the calls to a API controller must be prefixed with “api”. That’s why I set the url to “api/todos” in the backbone model.

Posted by cibrax | 2 comment(s)

Although JQuery provides a very good support for caching responses from AJAX calls in the browser, it is always good to know how you can use http as protocol for making an effective use of it.

The first thing you need to do on the server side is to supports HTTP GETs, and identify your resources with different URLs for retrieving the data (The resource in this case could be just a MVC action). If you use the same URL for retrieving different resource representations, you are doing it wrong. An HTTP POST will not work either as the response can not cached. Many devs typically use HTTP POSTs for two reason, they want to make explicit the data can not be cached or they use it as workaround for avoiding JSON hijacking attacks, which can be avoided anyways in HTTP GETs by returning a JSON array.

The ajax method in the JQuery global object provides a few options for supporting caching and conditional gets,

$.ajax({
    ifModified: [true|false],
    cache: [true|false],
});

The “ifModified” flag specifies whether we want to support conditional gets in the ajax calls. JQuery will automatically handle everything for us by picking the last received “Last-Modified” header from the server, and sending that as “If-Modified-Since” in all the subsequent requests. This requires that our MVC controller implements conditional gets. A conditional get in the context of http caching is used to revalidate an expired entry in the cache. If JQuery determines an entry is expired, it will be first try to revalidate that entry using a conditional get against the server. If the response returns an status code 304 (Not modified), JQuery will reuse the entry in the cache. In that way, we can save some of the bandwidth required to download the complete payload associated to that entry from the server.

The “cache” option basically overrides all the caching settings sent by the server as http headers. By setting this flag to false, JQuery will add an auto generated timestamp in the end of the URL to make it different from any previous used URL, so the browser will not know how to cache the responses.

Let’s analyze a couple scenarios.

The server sets a No-Cache header on the response

The server is the king. If the server explicitly states the response can not be cached, JQuery will honor that. The “cache” option on the ajax call will be completely ignored.

$('#nocache').click(function () {
    $.ajax({
        url: '/Home/NoCache',
        ifModified: false,
        cache: true,
        success: function (data, status, xhr) {
            $('#content').html(data.count);
        }
    });
});
public ActionResult NoCache()
{
   Response.Cache.SetCacheability(HttpCacheability.NoCache);
   return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
}

The server sets an Expiration header on the response

Again, the server is always is the one in condition for setting an expiration time for the data it returns. The entry will cached on the client side using that expiration setting.

$('#expires').click(function () {
    $.ajax({
        url: '/Home/Expires',
        ifModified: false,
        cache: true,
        success: function (data, status, xhr) {
            $('#content').html(data.count);
        }
    });
});
public ActionResult Expires()
{
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
    return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
}

The client never caches the data

The client side specifically states the data must be always fresh and the cache not be used. This means the “cache” option is set to false. No matter what the server specifies, JQuery will always generate an unique URL so that will be impossible to cache.

$('#expires_nocache').click(function () {
    $.ajax({
        url: '/Home/Expires',
        ifModified: false,
        cache: false,
        success: function (data, status, xhr) {
            $('#content').html(data.count);
        }
    });
});
public ActionResult Expires()
{
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
    return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
}

The client and server use conditional gets for validating the cached data.

The client puts a new entry in the cache, which will be validated after its expiration.  The server side must implement a conditional GET using either ETags or the last modified header.

$('#expires_conditional').click(function () {
    $.ajax({
        url: '/Home/ExpiresWithConditional',
        ifModified: true,
        cache: true,
        success: function (data, status, xhr) {
            $('#content').html(data.count);
        }
    });
});
public ActionResult ExpiresWithConditional()
{
    if (Request.Headers["If-Modified-Since"] != null && Count % 2 == 0)
    {
        return new HttpStatusCodeResult((int)HttpStatusCode.NotModified);
    }
    
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
    Response.Cache.SetLastModified(DateTime.Now);
 
    return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
}

The MVC action in the example above is only an example. In a real implementation, the server should be able to know whether the data has changed since the last time it was served or not.

Posted by cibrax | 2 comment(s)
Filed under: , ,

Another important milestone in my career started three years ago when I joined Tellago. I convinced my friend Jesus to hire me, and I would eventually move to the United States with my family to work in the company.  That never occurred for some personal things, but I fortunately had a chance to create an excellent team of very talented people in Argentina. I started myself working remotely from Argentina, and the things went so well for the company that we end up hiring more than 15 great architects down here in Argentina.  Creating this team was a very interesting and completely new challenge in my career.

I also got involved in a lot of interesting projects, and what is more important, I had a chance to work and met great people, which is what it really worth it.

However, a month ago, I decided it was about time to start a personal project with a good friend of mine, and that’s how AgileSight was born. Although the initial conception of the company was to create software products, we will also offering software consulting and development services. I am definitely very excited to be part of this new venture and face all new kind of challenges ahead.

My first assignment in AgileSight couldn’t be better as I will be working in the next Web Mobile Guidance project (Liike project) with the Microsoft Patterns & Practices team.

Posted by cibrax | 1 comment(s)
Filed under: ,
More Posts