我对我们向客户返回错误的方式有顾虑。

当我们得到一个错误时,我们是否通过抛出HttpResponseException立即返回错误:

public void Post(Customer customer)
{
    if (string.IsNullOrEmpty(customer.Name))
    {
        throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest) 
    }
    if (customer.Accounts.Count == 0)
    {
         throw new HttpResponseException("Customer does not have any account", HttpStatusCode.BadRequest) 
    }
}

或者我们把所有错误都加起来,然后发送回客户端:

public void Post(Customer customer)
{
    List<string> errors = new List<string>();
    if (string.IsNullOrEmpty(customer.Name))
    {
        errors.Add("Customer Name cannot be empty"); 
    }
    if (customer.Accounts.Count == 0)
    {
         errors.Add("Customer does not have any account"); 
    }
    var responseMessage = new HttpResponseMessage<List<string>>(errors, HttpStatusCode.BadRequest);
    throw new HttpResponseException(responseMessage);
}

这只是一个示例代码,无论是验证错误还是服务器错误都不重要,我只是想知道最佳实践,每种方法的优点和缺点。


当前回答

你可以抛出一个HttpResponseException

HttpResponseMessage response = 
    this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "your message");
throw new HttpResponseException(response);

其他回答

你可以抛出一个HttpResponseException

HttpResponseMessage response = 
    this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "your message");
throw new HttpResponseException(response);

其中一些答案似乎是过去的遗迹。我发现下面的解决方案既简单又有效。这是在. net 6中用于从ControllerBase派生的Web API。

而不是抛出异常,你可以直接返回各种HTTP响应代码作为对象,以及一个准确的错误消息:

using Microsoft.AspNetCore.Mvc;

[ApiController]
public class MyWebApiController : ControllerBase
{
    [HttpPost]
    public IActionResult Process(Customer customer)
    {
        if (string.IsNullOrEmpty(customer.Name))
            return BadRequest("Customer Name cannot be empty");

        if (!Customers.Find(customer))
            return NotFound("Customer does not have any account");

        // After validating inputs, core logic goes here...

        return Ok(customer.ID);  // or simply "return Ok()" if not returning data
    }
}

请在这里查看可用的错误代码列表。

至于什么时候返回错误(OP的问题),这取决于需求。在错误发生时返回错误意味着您可以避免额外处理的开销,但随后客户机必须重复调用以获取所有错误。还要考虑服务器视点,因为当发生错误时,它可能导致不希望的程序行为继续服务器端处理。

如果您正在使用ASP。NET Web API 2,最简单的方法是使用ApiController Short-Method。这将导致一个BadRequestResult。

return BadRequest("message");

ASP。NET Web API 2确实简化了它。例如,以下代码:

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

当没有找到该项时,返回以下内容到浏览器:

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Aug 2012 23:27:18 GMT
Content-Length: 51

{
  "Message": "Product with id = 12 not found"
}

建议:除非有灾难性错误(例如WCF Fault Exception),否则不要抛出HTTP Error 500。选择一个表示数据状态的适当HTTP状态代码。(请参阅下面的apigee链接。)

链接:

ASP中的异常处理。NET Web API (asp.net) 而且 RESTful API设计:错误怎么办?(apigee.com)

只是更新一下ASP的当前状态。净之前。接口现在被称为IActionResult,实现没有太大变化:

[JsonObject(IsReference = true)]
public class DuplicateEntityException : IActionResult
{        
    public DuplicateEntityException(object duplicateEntity, object entityId)
    {
        this.EntityType = duplicateEntity.GetType().Name;
        this.EntityId = entityId;
    }

    /// <summary>
    ///     Id of the duplicate (new) entity
    /// </summary>
    public object EntityId { get; set; }

    /// <summary>
    ///     Type of the duplicate (new) entity
    /// </summary>
    public string EntityType { get; set; }

    public Task ExecuteResultAsync(ActionContext context)
    {
        var message = new StringContent($"{this.EntityType ?? "Entity"} with id {this.EntityId ?? "(no id)"} already exist in the database");

        var response = new HttpResponseMessage(HttpStatusCode.Ambiguous) { Content = message };

        return Task.FromResult(response);
    }

    #endregion
}