参考:https://docs.microsoft.com/zh-cn/aspnet/web-api/overview/error-handling/exception-handling
①HttpResponseException
HttpResponseException类型是一种特殊情况。 此异常将返回异常构造函数中指定任何 HTTP 状态代码。 例如,以下方法将返回 404,找不到,如果id参数无效。
这个异常并不会触发我们的异常过滤器
[HttpGet] public async Task<IHttpActionResult> GetTest() { HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.NotFound) { Content = new StringContent("没有找到ID值") }; //这并不会触发我们的异常过滤器,他会直接返回 throw new HttpResponseException(resp); }
②异常筛选器
您可以自定义 Web API 通过编写处理异常的方式异常筛选器。 异常筛选器时,控制器方法引发任何未处理的异常时执行不 HttpResponseException异常。 HttpResponseException类型是一种特殊情况,因为它专为返回的 HTTP 响应。
异常筛选器实现System.Web.Http.Filters.IExceptionFilter接口。 编写异常筛选器的最简单方法是从派生System.Web.Http.Filters.ExceptionFilterAttribute类并重写OnException方法。
public class MyExceptionFilterAttribute : ExceptionFilterAttribute { public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { object obj = new { errcode = -1, errmsg = actionExecutedContext.Exception }; actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented) { Content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json") }; //可以根据具体情况判断 //if (actionExecutedContext.Exception is NotImplementedException) //{ // actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented) // { // Content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json") // }; //} //else //{ // actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError); //} return base.OnExceptionAsync(actionExecutedContext, cancellationToken); } }
放在我们的控制器上面:
[HttpGet] public async Task<IHttpActionResult> GetTest2() { //主动抛出异常 throw new NotImplementedException("代码出错"); } [HttpGet] public async Task<IHttpActionResult> GetTest3() { //自动处理异常 string a = "a"; int i = int.Parse(a); return await Task.FromResult(Ok("")); }
③HttpError
HttpError对象提供一致的方法来响应正文中返回的错误信息。 下面的示例演示如何返回 HTTP 状态代码 404 (找不到) 与HttpError响应正文中。也是直接返回内容,并不会触发异常。
[HttpGet] public async Task<IHttpActionResult> GetTest4() { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "错了脆了")); }
全局异常:下面的异常也无法捕捉
1.从控制器的构造函数引发的异常。
2.从消息处理程序引发的异常。
3.在路由期间引发的异常。
4.响应内容序列化期间引发的异常。
④IExceptionLogger(异常记录器)和 IExceptionHandler(异常处理程序)
异常记录器是查看所有未处理的异常捕获到由 Web API 的解决方案。
异常处理程序是用于自定义所有可能的响应未经处理的异常捕获到由 Web API 的解决方案。
异常筛选器是最简单的解决方案用于处理与特定操作或控制器相关的子集未经处理的异常。
这里我们用IExceptionHandler来完成我们的异常的处理。
创建我们的异常类
public class MyExceptionHandler : ExceptionHandler { public override Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) { object obj = new { errcode = -1, errmsg = context.Exception }; context.Result = new MyErrorResult { Request = context.ExceptionContext.Request, Content =JsonConvert.SerializeObject(obj) }; return base.HandleAsync(context, cancellationToken); } } public class MyErrorResult : IHttpActionResult { public HttpRequestMessage Request { get; set; } public string Content { get; set; } /// <summary> /// 执行 /// </summary> /// <param name="cancellationToken"></param> /// <returns></returns> public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.InternalServerError); response.Content = new StringContent(Content, Encoding.UTF8, "application/json"); response.RequestMessage = Request; return Task.FromResult(response); } }
注册全局: WebApiConfig中
// Web API 配置和服务 config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());
效果跟上面是一样的