1. HttpResponseException

var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
{
    Content = new StringContent(string.Format("No product with ID = {0}", id)),
    ReasonPhrase = "Product ID Not Found"
};
throw new HttpResponseException(resp);

2. Exception Filters

you can customize how Web API handles exceptions by writing an exception filter. An exception filter is executed when a controller method throws any unhandled exception that is not an HttpResponseException exception.

The HttpResponseException type is a special case, because it is designed specifically for returning an HTTP response. HttpResponseException 特殊,它是专门设计用来返回一个http响应, 不会走定义的 Exception Filter流程)

Exception filters in ASP.NET Web API are similar to those in ASP.NET MVC.

However, they are declared in a separate namespace and function separately.

In particular, the HandleErrorAttribute class used in MVC does not handle exceptions thrown by Web API controllers.

3. HttpError

public HttpResponseMessage GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        var message = string.Format("Product with id = {0} not found", id);
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
    }
    else
    {
        return Request.CreateResponse(HttpStatusCode.OK, item);
    }
}

CreateErrorResponse is an extension method defined in the System.Net.Http.HttpRequestMessageExtensions class. Internally, CreateErrorResponse creates an HttpError instance and then creates an HttpResponseMessage that contains the HttpError.

4. HttpError & Model Validation

public HttpResponseMessage PostProduct(Product item)
{
    if (!ModelState.IsValid)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }

    // Implementation not shown...
}
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 320

{
  "Message": "The request is invalid.",
  "ModelState": {
    "item": [
      "Required property 'Name' not found in JSON. Path '', line 1, position 14."
    ],
    "item.Name": [
      "The Name field is required."
    ],
    "item.Price": [
      "The field Price must be between 0 and 999."
    ]
  }
}

5. HttpError & HttpResponseException

public Product GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        var message = string.Format("Product with id = {0} not found", id);
        throw new HttpResponseException(
            Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
    }
    else
    {
        return item;
    }
}