user1943020
user1943020

Reputation:

Is there any difference between CreateResponse<Content>() and CreateResponse() with Web Api?

Given the following:

    [HttpGet]
    [ActionName("GetContent")]
    public HttpResponseMessage GetContent(int id)
    {
        Content content = _uow.Contents.GetById(id);
        if (content == null)
        {
            var message = string.Format("Content with id = {0} not found", id);
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.OK, content);
        }
    }

and:

    [HttpGet]
    [ActionName("GetContent")]
    public HttpResponseMessage GetContent(int id)
    {
        try
        {
            Content content = _uow.Contents.GetById(id);
            if (content == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }
            return Request.CreateResponse<Content>(HttpStatusCode.OK, content);
        }
        catch (Exception ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
        } 

    }

I have seen two coding styles. One using exceptions and the other not. One using CreateResponse<> and the other CreateResponse(). Can someone tell what are the advantages / disadvantages of using these? As far as I can see the second method seems to look more complete but is it really needed to use a try / catch for something as simple as this?

Upvotes: 3

Views: 6600

Answers (1)

Mike Wasson
Mike Wasson

Reputation: 6622

The main benefit to throwing HttpResponseException is when your action method returns a model type rather than an HttpResponseMessage. For example:

public Product Get(int id) 
{
    Product p = _GetProduct(id);
    if (p == null)
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
    return p;
}

This is equivalent to the following:

public HttpResponseMessage Get(int id) 
{
    Product p = _GetProduct(id);
    if (p == null)
    {
        return Request.CreateResponse(HttpStatusCode.NotFound);
    }
    return Request.CreateResponse(HttpStatusCode.OK, p);
}

It's OK to choose either style.

You shouldn't catch HttpResponseExceptions, because the point is for the Web API pipeline to catch them and translate them into HTTP responses. In your second code example, the Not Found error gets caught and turned into a Bad Request error, when you really wanted the client to receive Not Found (404).

Longer answer:

CreateResponse vs CreateResponse<T> has nothing to do with using HttpResponseException.

CreateResponse returns an HTTP response with no message body:

public HttpResponseMessage Get()
{
    return Request.CreateResponse(HttpStatusCode.NotFound);
}

CreateResponse<T> takes an object of type T and writes the object into the body of the HTTP response:

public HttpResponseMessage Get()
{
    Product product = new Product();
    // Serialize product in the response body
    return Request.CreateResponse<Product>(HttpStatusCode.OK, product);  
}

The next example is exactly the same but uses type inference to leave out the generic type parameter:

public HttpResponseMessage Get()
{
    Product product = new Product();
    // Serialize product in the response body
    return Request.CreateResponse(HttpStatusCode.OK, product);  
}

The CreateErrorResponse method creates an HTTP response whose response body is an HttpError object. The idea here is to use a common message format for error responses. Calling CreateErrorResponse is basically the same as this:

HttpError err = new HttpError( ... )
// Serialize err in the response.
return Request.CreateResponse(HttpStatusCode.BadRequest, err);

Upvotes: 13

Related Questions