本文转载请联系码农阅读公众号。Microsoft的ASP.NETWebAPI是一个轻量级的Web框架,可用于构建基于http的无状态rest服务。异常是运行时错误,异常处理是处理运行时错误的技术。每个开发人员都应该知道如何在WebAPI中处理异常,并在Action中用适当的错误代码和错误消息包装它们。WebAPI中的HttpResponseException在Action中可以使用HttpResponseException来包装指定的HttpCode和HttpMessage,如下例所示:HttpStatusCode.NotFound){Content=newStringContent("Employeedoesn'texist",System.Text.Encoding.UTF8,"text/plain"),StatusCode=HttpStatusCode.NotFound}thrownewHttpResponseException(response);}returnemp;}如果你的Action返回IHttpActionResult,那么GetEmployee()方法可以修改如下:'texist",System.Text.Encoding.UTF8,"text/plain"),StatusCode=HttpStatusCode.NotFound}thrownewHttpResponseException(response);}returnOk(emp);}从上面代码可以看出,错误码和error消息已分配到Response对象,然后包装在HttpResponseException中以供返回。除了在WebAPI中使用HttpError直接实例化HttpResponseMessage类,还可以使用Request.CreateErrorResponse()快速创建HttpResponseMessage类,如下代码所示:if(emp==null){stringmessage="Employeedoesn'texist";thrownewHttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound,message));}returnOk(emp);}WebAPI中使用的异常过滤器是一种可以捕获那些异常的方法不是获取处理后的异常过滤器,创建异常过滤器需要实现IExceptionFilter接口,但是这种方法比较麻烦,比较快的方法是直接继承ExceptionFilterAttribute,重写里面的OnException()方法,这是因为ExceptionFilterAttribute类本身就实现了IExceptionFilter接口,如下代码所示:[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,Inherited=true,AllowMultiple=true)]publicabstractclassExceptionFilterAttribute:FilterAttribute,IExceptionFilter,IFilter{protectedExceptionFilterAttribute();publicvirtualvoidOnException(HttpActionExecutedContextactionExecutedContext);publicvirtualTask??OnExceptionAsync(HttpActionExecutedContextactionExecutedContext,CancellationTokencancellationToken);}以下代码片段显示了如何通过覆盖ExceptionFilterAttribute.OnException()方法来创建自定义异常过滤器。PleasenotehowthefollowingcodecapturestheexceptionthrownintheActionandcaptures到的异常转换为HttpStatusResponse实体,然后塞入合适的httpcode和httpmessage,如下代码所示:publicclassCustomExceptionFilter:ExceptionFilterAttribute{publicoverridevoidOnException(HttpActionExecutedContextactionExecutedContext){HttpStatusCodestatus=HttpStatusCode.InternalServerError;Stringmessage=String.Empty;varexceptionType=actionExecutedContext.Exception.GetType();if(exceptionType==typeof(UnauthorizedAccessException)){message="AccesstotheWebAPIisnotauthorized.";status=HttpStatusCode.Unauthorized;}elseif(exceptionType==typeof(DivideByZeroException)){message="InternalServerError.";status=HttpStatusCode。InternalServerError;}else{message="Notfound.";status=HttpStatusCode.NotFound;}actionExecutedContext.Response=newHttpResponseMessage(){Content=newStringContent(message,System.Text.Encoding.UTF8,"text/plain"),StatusCode=status};base.OnException(actionExecutedContext);}}接下来,将自定义异常过滤器添加到HttpConfiguration全局集合中,如下代码所示:publicstaticvoidRegister(HttpConfigurationconfig){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(newCustomExceptionFilter());}除了全局设置自定义异常,你还可以将粒度缩小到Controller或Action级别。下面的代码展示了如何设置ItscontrolisonActionandController包装异常信息,default在某些情况下,当WebAPI抛出异常时,系统默认使用HttpStateCode=500作为响应,即:InternalServerError。场景来了,如果可以使用HttpResponseException,就可以改变这个系统默认行为,自动定义错误代码和错误信息,让结果更加清晰和语义化。翻译链接:https://www.infoworld.com/article/2994111/how-to-handle-errors-in-aspnet-web-api.html
