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
.