在 ASP.NET Web API 中返回错误的最佳实践 [英] Best practice to return errors in ASP.NET Web API

查看:29
本文介绍了在 ASP.NET Web API 中返回错误的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对我们向客户返回错误的方式感到担忧.

I have concerns on the way that we returns errors to client.

我们是否通过抛出 HttpResponseException 当我们收到错误时:

Do we return error immediately by throwing HttpResponseException when we get an error:

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

或者我们累积所有错误然后发送回客户端:

Or we accumulate all errors then send back to client:

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

这只是一个示例代码,验证错误或服务器错误都没有关系,我只想知道最佳实践,每种方法的优缺点.

This is just a sample code, it does not matter either validation errors or server error, I just would like to know the best practice, the pros and cons of each approach.

推荐答案

对我来说,我通常会发回一个 HttpResponseException 并根据抛出的异常以及异常是否是致命的或not 将确定我是否立即发回 HttpResponseException.

For me I usually send back an HttpResponseException and set the status code accordingly depending on the exception thrown and if the exception is fatal or not will determine whether I send back the HttpResponseException immediately.

归根结底,它是一个 API 发送回响应而不是视图,所以我认为向消费者发送带有异常和状态代码的消息是可以的.我目前不需要累积错误并将它们发回,因为大多数异常通常是由于不正确的参数或调用等造成的.

At the end of the day it's an API sending back responses and not views, so I think it's fine to send back a message with the exception and status code to the consumer. I currently haven't needed to accumulate errors and send them back as most exceptions are usually due to incorrect parameters or calls etc.

我的应用程序中的一个例子是有时客户端会要求数据,但没有任何数据可用,所以我抛出一个自定义 NoDataAvailableException 并让它冒泡到 Web API 应用程序,其中然后在我的自定义过滤器中捕获它发送回相关消息以及正确的状态代码.

An example in my app is that sometimes the client will ask for data, but there isn't any data available so I throw a custom NoDataAvailableException and let it bubble to the Web API app, where then in my custom filter which captures it sending back a relevant message along with the correct status code.

我不能 100% 确定最佳做法是什么,但这目前对我有用,所以这就是我正在做的.

I am not 100% sure on what's the best practice for this, but this is working for me currently so that's what I'm doing.

更新:

自从我回答了这个问题以来,已经写了一些关于该主题的博客文章:

Since I answered this question a few blog posts have been written on the topic:

https://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling

(这个在每晚构建中有一些新功能)https://docs.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi

(this one has some new features in the nightly builds) https://docs.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi

更新 2

更新我们的错误处理流程,我们有两种情况:

Update to our error handling process, we have two cases:

  1. 对于一般错误,如未找到,或传递给操作的参数无效,我们返回 HttpResponseException 以立即停止处理.此外,对于我们操作中的模型错误,我们会将模型状态字典交给 Request.CreateErrorResponse 扩展并将其包装在 HttpResponseException 中.添加模型状态字典会生成在响应正文中发送的模型错误列表.

  1. For general errors like not found, or invalid parameters being passed to an action we return a HttpResponseException to stop processing immediately. Additionally for model errors in our actions we will hand the model state dictionary to the Request.CreateErrorResponse extension and wrap it in a HttpResponseException. Adding the model state dictionary results in a list of the model errors sent in the response body.

对于发生在更高层的错误,服务器错误,我们让异常冒泡到 Web API 应用程序,这里我们有一个全局异常过滤器,它查看异常,用 ELMAH 记录它并尝试使其有意义它在 HttpResponseException 中再次设置正确的 HTTP 状态代码和相关的友好错误消息作为正文.对于我们不期望客户端会收到默认的 500 内部服务器错误的例外情况,而是出于安全原因的通用消息.

For errors that occur in higher layers, server errors, we let the exception bubble to the Web API app, here we have a global exception filter which looks at the exception, logs it with ELMAH and tries to make sense of it setting the correct HTTP status code and a relevant friendly error message as the body again in a HttpResponseException. For exceptions that we aren't expecting the client will receive the default 500 internal server error, but a generic message due to security reasons.

更新 3

最近,在选择 Web API 2 后,为了发送回一般错误,我们现在使用 IHttpActionResult 接口,特别是 System.Web.Http.Results 命名空间中的内置类,例如 NotFound,BadRequest 当它们适合时,如果它们不适合我们扩展它们,例如带有响应消息的 NotFound 结果:

Recently, after picking up Web API 2, for sending back general errors we now use the IHttpActionResult interface, specifically the built in classes for in the System.Web.Http.Results namespace such as NotFound, BadRequest when they fit, if they don't we extend them, for example a NotFound result with a response message:

public class NotFoundWithMessageResult : IHttpActionResult
{
    private string message;

    public NotFoundWithMessageResult(string message)
    {
        this.message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(HttpStatusCode.NotFound);
        response.Content = new StringContent(message);
        return Task.FromResult(response);
    }
}

这篇关于在 ASP.NET Web API 中返回错误的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆