When to use Response.CreateResponse versus HttpResponseException with Web Api

You need to use throw HttpResponseException if you're returning a HTTP error status code if you want Transactions to roll back.
February 05 2013

When I first started using and learning .NET Web Api late last year I, like most I expect, used the MSDN documentation, Pluralsight training videos, and the Todo project that comes with the recent VS 2012 SPA (Single Page App) template addition.  In this SPA template HttpResponseException is thrown from GET methods, while Request.CreateResponse is used from POST, PUT, DELETE methods.  For example, using either of the following

throw new HttpResponseException(HttpStatusCode.NotFound);
// or
return Request.CreateResponse(HttpStatusCode.NotFound);

Both return the same data to the client, so they're basically equivalent right?  I followed this practice with my code. Where I differ is that I use an Action Filter to control NHibernate Transactions.  Returning Request.CreateResponse to indicate error conditions does not rollback any transaction created by the Action Filter.  For transactions to be implicity rolled back an Exception needs to be thrown.

If you're modifying data in your PUT, POST, or DELETE (which everyone does) you'll need to throw HttpResponseException if you want any ambient transactions to be rolled back.  You can still use Request.CreateResponse though, if you haven't modified anything within the transaction yet.

(GET's throw an exception when they don't return a HttpResponseMessage - otherwise you could also call Request.CreateResponse from within GET methods).

A simple solution is anywhere you are calling Request.CreateResponse and should be calling throw new HttpResponseException, just wrap the response in the exception.

// Make some changes to your ORM entity.

// Check for validity or business rules on your entity
if (entity.DoNotPersistMe()) {
    var errorResponse = Response.CreateResponse(HttpStatusCode.BadRequest);
    throw new HttpResponseException(errorResponse);
}

Post a comment

comments powered by Disqus