返回适当的消息给主叫客户端

时间:2019-06-07 09:56:23

标签: c# rest asp.net-web-api error-handling controller

这非常相似,但是我的问题不同:Return content with IHttpActionResult for non-OK response

考虑到问题是不同的,我要求提供更简洁的答案(如果存在)。

我的体系结构如下:

  1. 对后端控制器的Javascript / jQuery调用
  2. 后端控制器调用WebAPI服务
  3. WebAPI服务查询数据库(等)并返回数据

我有以下简化代码(Web API)...

如果产品ID不存在,示例1返回错误:

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) => p.Id == id);
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}

示例2如果产品ID不存在,则返回空数据:

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) => p.Id == id);
    return Ok(product);
}

客户端JS:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('Product retrieved'); })
.fail(function() { alert('Product doesn't exist. '); })
.always(function() { ... });

我已经读过很多遍了,使用异常来控制流是不好的做法,实际上,如果我使用NotFound()会发生什么,因为它将击中.fail函数,这表明存在错误(没有)。

在另一种情况下,评论必须由插入评论的人以外的其他人批准:

public IHttpActionResult ApproveComment(int rowId, string userName)
{
    try {
        return Ok(BusinessLogicLayer.ApproveComment(rowId, userName));
    }
    catch(Exception ex)
    { 
        // elmah.logerr...
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.InnerException == null ? ex.Message : ex.InnerException.Message));
    }
}

BusinessLogicLayer:
public string ApproveComment(int rowId, string userName)
{
    if (userName == _repository.GetInsertedCommentUserName()) {
        return "You cannot approve your own comment.";
    }
    if(_repository.ApproveComment(rowId, userName)){
        return "Comment approved";
    }
}

OR

public string ApproveComment(int rowId, string userName)
{
    if (userName == _repository.GetInsertedCommentUserName()) {
        throw new Exception("You cannot approve your own comment.");
    }
    if(_repository.ApproveComment(rowId, userName)){
        return "Comment approved";
    }
}

在不使用异常的情况下向用户返回适当消息的干净优雅的方法是什么?

还是我的想法是错误的,从用户的角度来看是“例外”情况吗? IE。,“当我传递此ID时,我希望得到一个返回的产品,但可惜它不存在!”从开发人员/测试人员的角度来看,我认为这不是例外,但从最终用户的角度来看-也许。

3 个答案:

答案 0 :(得分:2)

您要问两个不同的问题。因此,让我们一个接一个地回答他们。

“未找到”问题

在第一种情况下,客户端尝试访问不存在的产品。从服务器返回的适当状态码是404(未找到)。对于客户端,这实际上是一个例外情况,因为它可能正在尝试访问现有资源。然后,在客户端javascript的“失败”部分,您可以检查请求失败的原因(4xx范围=客户端错误,5xx范围=服务器端错误),并向用户显示适当的消息。

“批准”问题

对于已批准的问题,您将返回无用的状态码。在批准之前,您应该检查客户端尝试批准的资源是否存在。如果资源不存在,这是客户端错误,您应该返回404(未找到)。 如果由于某种原因业务逻辑层对资源的更新仍然失败,并且这是服务器问题,则应返回500,内部服务器错误。如果是客户端故障,则更新失败,请返回4xx范围内的状态码。 (例如403,未经授权,如果不允许客户批准自己的评论)

答案 1 :(得分:1)

批准您自己的评论-这似乎是无效的操作。有一个例外。

这是来自客户端的错误请求。有一个响应状态代码。

在代码中有异常,如果您可以相应地处理它们,那没有错。如果您在客户端优雅地处理了4xx状态代码,那么给出4xx状态代码也没有错。 这是不应让客户提出的请求,所以它应该失败,不是吗?

您的第二个示例与第一个示例不同。在第二个示例中,您肯定将无法实现目标。这是一个错误请求

第一个示例很好,您尝试实现默认情况下不禁止的操作-获取具有给定id的记录。并且碰巧这种情况是该记录不存在。在这种情况下,您的项目未找到

答案 2 :(得分:0)

您可以使用 HttpResponseMessage 自定义响应消息。它允许设置状态代码、原因短语、消息和许多其他内容。