博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何友好的处理 WebApi 中抛出的错误
阅读量:4033 次
发布时间:2019-05-24

本文共 4856 字,大约阅读时间需要 16 分钟。

微软的 ASP.NET Web API 是一个轻量级的web框架,可用来构建基于 http 无状态的rest服务,异常是一种运行时错误,异常处理是一种处理运行时错误的技术,每一个开发者都应该知道如何处理 Web API 中的异常,并且在 Action 中使用合适的 错误码错误信息 进行包装。

WebAPI 中的 HttpResponseException

你可以在 Action 中使用 HttpResponseException 来包装指定的 HttpCode 和 HttpMessage,如下例子所示:

public Employee GetEmployee(int id){    Employee emp = employeeRepository.Get(id);    if (emp == null)    {        var response = new HttpResponseMessage(HttpStatusCode.NotFound)        {            Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),            StatusCode = HttpStatusCode.NotFound        }        throw new HttpResponseException(response);    }    return emp;}

如果你的 Action 返回的是 IHttpActionResult,那么可将 GetEmployee() 方法修改如下:

public IHttpActionResult GetEmployee(int id){    Employee emp = employeeRepository.Get(id);    if (emp == null)    {        var response = new HttpResponseMessage(HttpStatusCode.NotFound)        {            Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),            StatusCode = HttpStatusCode.NotFound        }        throw new HttpResponseException(response);    }    return Ok(emp);}

从上面的代码可以看出,错误码 和 错误消息 都赋给了 Response 对象,然后包装到了 HttpResponseException 进行返回。

WebAPI 中使用 HttpError

除了直接实例化 HttpResponseMessage 类,还可以使用 Request.CreateErrorResponse() 快捷的创建 HttpResponseMessage 类,如下代码所示:

public IActionResult GetEmployee(int id){    Employee emp = employeeRepository.Get(id);    if (emp == null)    {       string message = "Employee doesn't exist";        throw new HttpResponseException(            Request.CreateErrorResponse(HttpStatusCode.NotFound, message));    }    return Ok(emp);}

WebAPI 中使用 异常过滤器

异常过滤器是一种可以在 WebAPI 中捕获那些未得到处理的异常的过滤器,要想创建异常过滤器,你需要实现 IExceptionFilter 接口,不过这种方式比较麻烦,更快捷的方法是直接继承 ExceptionFilterAttribute 并重写里面的 OnException() 方法即可,这是因为 ExceptionFilterAttribute 类本身就实现了 IExceptionFilter 接口,如下代码所示:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]    public abstract class ExceptionFilterAttribute : FilterAttribute, IExceptionFilter, IFilter    {        protected ExceptionFilterAttribute();        public virtual void OnException(HttpActionExecutedContext actionExecutedContext);        public virtual Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken);    }

下面的代码片段展示了如何通过重写 ExceptionFilterAttribute.OnException() 方法来创建一个自定义异常过滤器,请注意下面的代码是如何捕获在 Action 中抛出的异常,并将捕获到的异常转换为 HttpStatusResponse 实体,然后塞入合适的 httpcode 和 httpmessage,如下代码所示:

    public class CustomExceptionFilter : ExceptionFilterAttribute    {        public override void OnException(HttpActionExecutedContext actionExecutedContext)        {            HttpStatusCode status = HttpStatusCode.InternalServerError;            String message = String.Empty;            var exceptionType = actionExecutedContext.Exception.GetType();            if (exceptionType == typeof(UnauthorizedAccessException))            {                message = "Access to the Web API is not authorized.";                status = HttpStatusCode.Unauthorized;            }            else if (exceptionType == typeof(DivideByZeroException))            {                message = "Internal Server Error.";                status = HttpStatusCode.InternalServerError;            }            else            {                message = "Not found.";                status = HttpStatusCode.NotFound;            }            actionExecutedContext.Response = new HttpResponseMessage()            {                Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),                StatusCode = status            };            base.OnException(actionExecutedContext);        }    }

接下来将自定义的异常过滤器添加到 HttpConfiguration 全局集合中,如下代码所示:

        public static void Register(HttpConfiguration config)        {            config.MapHttpAttributeRoutes();            config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{id}",                defaults: new { id = RouteParameter.Optional }            );            config.Formatters.Remove(config.Formatters.XmlFormatter);            config.Filters.Add(new CustomExceptionFilter());        }

除了将自定义异常设置到全局上,你还可以缩小粒度到 Controller 或者 Action 级别上,下面的代码分别展示了如何将其控制在 Action 和 Controller 上。

[DatabaseExceptionFilter]public class EmployeesController : ApiController{    //Some code} [CustomExceptionFilter] public IEnumerable
 Get() {    throw new DivideByZeroException();  }

ASP.NET Web API 提供了强大的 HttpResponseException 来包装异常信息,默认情况下,当 WebAPI 中抛出异常,系统默认使用 Http StateCode = 500 作为回应,也即:Internal Server Error. ,场景就来了,如果你会用 HttpResponseException 的话,就可以改变这种系统默认行为,自定义错误码和错误信息让结果更加清晰语义化。

译文链接:https://www.infoworld.com/article/2994111/how-to-handle-errors-in-aspnet-web-api.html

转载地址:http://roudi.baihongyu.com/

你可能感兴趣的文章
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
一个ahk小函数, 实现版本号的比较
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
Intellij IDEA启动优化,让开发的感觉飞起来
查看>>