What is the difference between HttpResponseMessage and HttpResponseException

C#asp.net Web-Api

C# Problem Overview


I tried to understand both and write sample code:

 public HttpResponseMessage Get()
 {
     var response = ControllerContext.Request
                         .CreateResponse(HttpStatusCode.BadRequest, "abc");

     throw new HttpResponseException(response);
 }

And:

 public HttpResponseMessage Get()
 {
     return ControllerContext.Request
                        .CreateResponse(HttpStatusCode.BadRequest, "abc");
 }

From Fiddle, I really didn't see any differences between them, so what is the purpose of using HttpResponseException?

C# Solutions


Solution 1 - C#

The main difference between the two is this. The exception is useful to immediately stop processing and exit. For example assume I have the following code

public class CustomerController : ApiController {
  private ICustomerContext repo;

  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }
  
  public Customer Get(int id) {
    var customer = repo.Customers.SingleOrDefault(c=>c.CustomerID == id);
    if (customer == null) {
      throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }
    return customer;
  }
}

If this code runs and I pass an id that is not present, it will immediately stop processing and return a status code of 404.

If instead I return HttpResponseMessage, the request will happily continue the rest of its processing and return a 404. The main difference being end the request or not.

As Darrel said the exception is useful in cases where in some cases I want processing to continue (as in when customer is found) and in others I don't.

The place where you might want to use something like HttpResponseMessage is in an Http POST to return a status code of 201 and set the location header. In that case I do want processing to continue. That would would do with this code.*

public class CustomerController : ApiController {
  private ICustomerContext repo;

  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }
  
  public HttpResponseMessage Post(Customer customer) {
    repo.Add(customer);
    repo.SaveChanges();
    var response = Request.CreateResponse(HttpStatusCode.Created, customer);
    response.Headers.Location = new Uri(Request.RequestUri, string.format("customer/{0}", customer.id));
    return response;
  }
}

*note: If you are using the beta bits you would create a new HttpResponseMessage. I am using the later bits however which require you to use the CreateResponse extension method off of the Request.

Above, I am creating a response which sets the status code to 201, passes in the customer, and then sets the location header.

The response is then returned and the request continues processing.

Hope this helps

Solution 2 - C#

HttpResponseException is useful when your Controller Action signature looks like

  Foo Get(int id)

In this case, you cannot easily return status code like 400.

Be aware that HttpResponseMessage<T> is going away in the next release of Web API.

Solution 3 - C#

Assuming you want to unit test the responses, doesn't it make sense to always return an HttpResponseMessage? I don't particularly like the idea of returning a straight type from an ApiController since it doesn't follow typical development patterns.

In a non-Web API class that fetched a Customer, you'd likely return null, with your calling code checking for a null response:

public Customer GetCustomer(int id)
{
    return db.Customers.Find(id);
}

But in Web API, you're not going to return null, you have to return something, even if that something is created after you throw an HttpResponseException. In that case, to ease testing, why not just always return an HttpResponseMessage, and make that your signature?

public HttpResponseMessage GetCustomer(int id)
{
    var customer = db.Customers.Find(id);
    if (customer == null)
    {
        return Request.CreateResponse(HttpStatusCode.NotFound);
    }
    
    return Request.CreateResponse(HttpStatusCode.OK, customer);
}

Solution 4 - C#

HttpResponseException derives from Exception and embeds HttpResponseMessage. Since it derives from Exception it can be useful in try-catch scenarios.

Default status code returned by HttpResponseException is HttpStatusCode.InternalServerError.

Solution 5 - C#

As the original questions states, there is no real difference in the returned Response.

The real purpose of HttpResponseException is to allow sub methods to create and 'throw' their own HttpResponseMessages that flow back to the up the call stack and are returned to the client.

public class CustomerController : ApiController {
  private ICustomerContext repo;
  public CustomerController(ICustomerContext repo) {
    this.repo = repo;
  }

  public HttpResponseMessage Get(int id) {

    Customer customer = getCustomer(id);
    
    return Request.CreateResponse(customer);
  }

  private Customer getCustomer(int id){
    .....do some work
    .....we have a problem so throw exception
    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, "Id out of range");
    return repo.Customers.SingleOrDefault(c=>c.CustomerID == id)
}

Forgive any mistakes, code written on the fly. The thrown HttpResponseException bubbles up thru the actions call stack, does not get caught by normal Exception handlers and returns its HttpResponseMessage like the action method itself would have.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncuongleView Question on Stackoverflow
Solution 1 - C#Glenn BlockView Answer on Stackoverflow
Solution 2 - C#Darrel MillerView Answer on Stackoverflow
Solution 3 - C#Brian VallelungaView Answer on Stackoverflow
Solution 4 - C#labilbeView Answer on Stackoverflow
Solution 5 - C#MikeeView Answer on Stackoverflow