Web API 异常处理解决方案
- 异常筛选器:在App_Start里面新建一个类WebApiExceptionFilterAttribute.cs(这实际上是定义了一个新的特性),它继承于ExceptionFilterAttribute类,但是我们需要重写里面的OnException()方法
- 在接口级别上使用新定义的异常类,同时还需要在自定义异常类WebApiExceptionFilterAttribute.cs中定义错误信息,页面显示"不好意思,该方法不支持",而且它的Status Code: 501 This Func is Not Supported
1 [App_Start.WebApiExceptionFilter] 2 [HttpGet] 3 public string GetData(){ 4 throw new NotImplementedException("不好意思,该方法不支持"); 5 }
- 在控制器级别使用异常过滤,直接在控制器上面标注特性即可;如果想要在多个控制器上同时启用异常过滤,可以建立一个基类控制器,在该基类控制器上标注特性,其他控制器继承该基类控制器即可
1 [App_Start.WebApiExceptionFilter] 2 public class TestException2Controller : ApiController{ 3 [HttpGet] 4 public string GetData(){ 5 throw new NotImplementedException("不好意思,该方法不支持"); 6 } 7 } 8 [App_Start.WebApiExceptionFilter] 9 public class TestExceptionBaseController : ApiController{ }
- 全部配置,对整个应用程序启用异常过滤
1 //在Global.asax全局配置里面添加 2 public class WebApiApplication : System.Web.HttpApplication{ 3 protected void Application_Start(){ 4 GlobalConfiguration.Configuration.Filters.Add(new App_Start.WebApiExceptionFilterAttribute()); 5 } 6 } 7 //在WebApiConfig.cs文件的Register方法里面添加 8 public static class WebApiConfig{ 9 public static void Register(HttpConfiguration config){ 10 config.Filters.Add(new App_Start.WebApiExceptionFilterAttribute()); 11 }}
- 使用HttpResponseException类自定义异常信息
- HttpResponseMessage 用于返回一个来自于客户端的请求结果讯息,可以使用 HttpResponseMessage 自订返回的内容,HttpResponseException 则是以当发生例外时用来返回客户端错误讯息
- 当呼叫 Web API 服务时发生了与预期上不同的错误时,理当应该中止程序返回错误讯息,这时对于错误的返回就该使用 HttpResponseException,而使用 HttpResponseMessage 则是代表着当客户端发送了一个工作请求而 Web API 正确的完成了这个工作,就能够使用 HttpResponseMessage 返回一个 201 的讯息,所以 HttpResponseMessage 与 HttpResponseException 在使用上根本的目标就是不同的,用 HttpResponseMessage 去返回一个例外错误也会让程序结构难以辨别且不够清晰
1 [HttpGet] 2 public string GetData_Ex(int id){ 3 if (id == 1){ 4 return "function is OK"; 5 }else{ 6 var response = new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound){ 7 Content = new StringContent("不好意思,没有找到"+id.ToString()), 8 ReasonPhrase = "object is not found" 9 }); 10 throw response; 11 } 12 }
- 使用HttpError对象提供一致的方法响应正文中返回的错误信息,二者都可以向客户端返回http状态码和错误讯息,并且都可以包含在HttpResponseException对象中发回到客户端;但是,一般情况下,HttpError只有在向客户端返回错误讯息的时候才会使用,而HttpResponseMessage对象既可以返回错误讯息,也可返回请求正确的消息
1 [HttpGet] 2 public HttpResponseMessage GetData_HttpError(){ 3 try{ 4 //业务逻辑 5 }catch (Exception ex){ 6 return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message); 7 } 8 return Request.CreateResponse(HttpStatusCode.OK, "OKOKOK"); 9 } 10
1 public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute{ 2 public override void OnException(HttpActionExecutedContext actionExecutedContext){ 3 //1.异常日志记录(正式项目里面一般是用log4net记录异常日志) 4 Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "——" + actionExecutedContext.Exception.GetType().ToString() + ":" + actionExecutedContext.Exception.StackTrace); 5 //2.返回调用方具体的异常信息 6 if (actionExecutedContext.Exception is NotImplementedException){ 7 actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented){ 8 Content = new StringContent("不好意思,该方法不支持"),//获取或设置 HTTP 响应消息的内容 9 ReasonPhrase = "不好意思,该方法不支持"//获取或设置通常由服务器发出的原因短语(与状态代码一起发出 10 }; 11 } 12 else if(actionExecutedContext.Exception is TimeoutException){ 13 actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.RequestTimeout); 14 } 15 else{ 16 //.....这里可以根据项目需要返回到客户端特定的状态码。如果找不到相应的异常,统一返回服务端错误500 17 actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError); 18 } 19 base.OnException(actionExecutedContext); 20 } 21 }