Implementing IHttpActionResult in Web API 2

Default return type

The default return type on Web API 2 controllers is a C# class or collection:

// GET: api/Test
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

I love that abstraction: the framework builds the http response; headers, response code, and serializes the C# class to JSON for the response body (although camelCase key names requires Json.net).

Limitations

The default return type does not allow the flexibility to modify the response; e.g. to include a different response code, which had previously been achieved by raising exceptions:

throw new HttpResponseException(HttpStatusCode.NotImplemented);

Additional power of IHttpActionResult return types

With Web API 2, Microsoft provided the IHttpActionResult interface, that we can implement to create a custom return type class. This is well documented by Microsoft, however, the provided example doesn't show how to return a serialized C# class as JSON, or how to set a response code.

Modifying Microsoft's example slightly:

public class JsonResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;
    HttpStatusCode  _statusCode;

    public JsonResult(string value, HttpRequestMessage request, HttpStatusCode statusCode)
    {
        _value = value;
        _request = request;
        _statusCode = statusCode;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request,
            StatusCode = _statusCode
        };
        return Task.FromResult(response);
    }
}

Custom response code

Note the addition of the HttpStatusCode argument in the JsonResult() method signature, and subsequent inclusion of the StatusCode property in the response object. Now, when calling JsonResult

Serializing objects to JSON

I found the solution in this Stack Overflow answer to be really elegant. A generic extension method to serialize any object into a JSON structure, usable with just object.ToJson().

The result

The custom JsonResult class, with the JSON extention method, can now be used to send a response in a single line:

return new JsonResult(myCollection.ToJson(), Request, HttpStatusCode.OK);

Note that the controller return type should be IHttpActionResult.