3

鉴于以下情况:

    [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);
        }
    }

和:

    [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);
        } 

    }

我见过两种编码风格。一个使用异常,另一个不使用。一个使用 CreateResponse<>,另一个使用 CreateResponse()。有人能说出使用这些的优点/缺点吗?据我所知,第二种方法看起来更完整,但真的需要使用 try / catch 来完成如此简单的事情吗?

4

1 回答 1

13

throwing 的主要好处HttpResponseException是当您的操作方法返回模型类型而不是HttpResponseMessage. 例如:

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

这等效于以下内容:

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

选择任何一种风格都可以。

您不应该 catch HttpResponseException,因为关键是 Web API 管道可以捕获它们并将它们转换为 HTTP 响应。在您的第二个代码示例中,当您真的希望客户端接收未找到(404)时,未找到错误被捕获并变成了错误请求错误。

更长的答案:

CreateResponsevsCreateResponse<T>与使用无关HttpResponseException

CreateResponse返回没有消息正文的 HTTP 响应:

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

CreateResponse<T>获取一个 T 类型的对象并将该对象写入 HTTP 响应的正文中:

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

下一个示例完全相同,但使用类型推断省略了泛型类型参数:

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

CreateErrorResponse方法创建一个 HTTP 响应,其响应主体是一个HttpError对象。这里的想法是对错误响应使用通用消息格式。调用CreateErrorResponse基本上是这样的:

HttpError err = new HttpError( ... )
// Serialize err in the response.
return Request.CreateResponse(HttpStatusCode.BadRequest, err);
于 2013-10-24T22:24:46.643 回答