webapi框架搭建-webapi异常处理
webapi框架搭建系列博客
前言
上一篇我们已经完成了项目的日志管理,在项目开发中日志会经常记录程序中的异常,供后续问题排查使用。本篇讲如何在webapi里加入异常处理机制。
目的和原则
1、程序任何地方都不能catch掉异常,如果要catch也请重新throw异常或是将异常记录到日志里。避免异常被“吃掉“,导致无法排查程序的bug。
2、webapi接口的”请求成功“和”请求失败“以一定的标准规范提供给外部
我的规范为:
所有的成功请求返回200(response的status为200),返回的结果以json封装
所有的失败请求返回非200,错误以json返回,错误的内容为Message的值,如{"Message":"这里是异常的内容描述"}
3、如果为已知异常(即我们代码里写的throw异常)可简单的记录到日志,但如果是未知异常(我们不知道是哪里抛出的异常,往往也是程序的bug)则记录到特殊的日志文件里,如上篇的log/error目录下。
参考
微软webapi异常处理:https://docs.microsoft.com/zh-cn/aspnet/web-api/overview/error-handling/
步骤如下
自定义异常类
此异常类即是”已知“异常,约定程序里我们自己抛出的异常都用此类,Message属性记录异常的描述信息
using System;
using System.Runtime.Serialization; namespace webapi.Exceptions
{
public class KnownException : Exception
{
public KnownException():base()
{
} public KnownException(string message) : base(message)
{
} public KnownException(string message, Exception innerException) : base(message, innerException)
{
} protected KnownException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
创建webapi异常过滤器
创建WebApiExceptionFilterAttribute类,代码如下
using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;
using log4net; namespace webapi.Exceptions
{
public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exception = actionExecutedContext.Exception;//获取产生的异常对象
var exceptionMessage = exception.Message;
var logMessage =
$@"controller.action={actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName}.{actionExecutedContext.ActionContext.ActionDescriptor.ActionName}:exception="
+ exception.Message;//异常内容
ILog log = LogManager.GetLogger(actionExecutedContext.ActionContext.ControllerContext.Controller.GetType());
if (exception is KnownException)
{
log.Debug(logMessage);
}
else
{
log.Error(logMessage, exception);
}
actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, exceptionMessage);
} }
}
在webapi里使用异常过滤最简单的方法就是继承自ExceptionFilterAttribute类,并重写OnException方法并写入自己的异常处理逻辑
将异常过滤器加到webapi里
修改之前的WebApiConfig.OwinWebApiConfiguration方法,代码如下
/// <summary>
/// 返回webapi的httpconfiguration配置
/// 用于webapi应用于owin技术时使用
/// </summary>
/// <returns></returns>
public static HttpConfiguration OwinWebApiConfiguration(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();//开启属性路由
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new WebApiExceptionFilterAttribute());
return config;
}
增加的只是config.Filters.Add(new WebApiExceptionFilterAttribute());这一句
测试结果
创建用于测试的控制器,写两个接口分别模拟程序bug抛出的未知异常和自己抛出的已知异常
using System;
using System.Web.Http;
using webapi.Exceptions; namespace webapi.example
{
[RoutePrefix("api/exceptionTest")]
public class ExceptionTestController : ApiController
{
/// <summary>
/// 模拟程序bug抛出的异常
/// </summary>
/// <returns></returns>
[Route("unknown"),HttpGet]
public IHttpActionResult UnKnow()
{
throw new Exception("未知的异常");
}
/// <summary>
/// 模拟主动抛出的业务异常
/// </summary>
/// <returns></returns>
[Route("known"), HttpGet]
public IHttpActionResult Know()
{
throw new KnownException("已知的异常");
}
}
}
返问两个接口会得到内容为{"Message":"xxx"},status为400的respose,和我们的约定规则一样。
webapi框架搭建-webapi异常处理的更多相关文章
- webapi框架搭建系列博客
webapi框架搭建系列博客 webapi框架搭建-创建项目(一) webapi框架搭建-创建项目(二)-以iis为部署环境的配置 webapi框架搭建-创建项目(三)-webapi owin web ...
- webapi框架搭建-依赖注入之autofac
前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...
- webapi框架搭建-创建项目(三)-webapi owin
上一篇:创建项目(二) 在上一篇里,我们已经创建好了webapi应用,并已经部署到iis里,本篇讲如何用owin自宿主或是iis宿主来部署webapi应用. owin介绍 传统的asp.net网站只能 ...
- webapi框架搭建-创建项目(二)-以iis为部署环境的配置
上篇:webapi快速框架搭建-创建项目(一) 在"创建项目(一)"这一篇里已经创建了一个空的项目,但项目上什么都没有,本篇描述如何将webapi配置成部署在iis上. 步骤 用n ...
- webapi框架搭建-日志管理log4net
前言 本篇讲怎么在前几篇已经创建好的项目里加上日志处理机制,我们采用Log4net技术.跟多的log4net技术的细节请查阅log4net的官网. log4net官网:http://logging.a ...
- webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制
webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...
- webapi框架搭建-安全机制(三)-简单的基于角色的权限控制
webapi框架搭建系列博客 上一篇已经完成了“身份验证”,如果只是想简单的实现基于角色的权限管理,我们基本上不用写代码,微软已经提供了authorize特性,直接用就行. Authorize特性的使 ...
- webapi框架搭建-安全机制(二)-身份验证
webapi框架搭建系列博客 身份验证(authentication)的责任是识别出http请求者的身份,除此之外尽量不要管其它的事.webapi的authentication我用authentica ...
- webapi框架搭建-安全机制(一)
本系列博客链接:webapi框架搭建系列博客 前言 webapi接口是开放给外部使用的,包括接口的地址,传参的规范,还有返回结果的说明.正因为接口的开放性,使得接口的安全很重要.试想一下,用抓包工具( ...
随机推荐
- PAT 1016 部分A+B
https://pintia.cn/problem-sets/994805260223102976/problems/994805306310115328 正整数A的“D~A~(为1位整数)部分”定义 ...
- HDU 2052 Picture
http://acm.hdu.edu.cn/showproblem.php?pid=2052 Problem Description Give you the width and height of ...
- 一种快速统计SQL Server每个表行数的方法
转载自:http://www.cnblogs.com/kenyang/archive/2013/04/09/3011447.html 我们都知道用聚合函数count()可以统计表的行数.如果需要统计数 ...
- Oracle 数据库启动过程
一 启动数据库 Oracle启动过程涉及几种模式,这些模式涉及不同的文件,每个状态下数据库做不同的事情,同时这些模式适用于不同的维护需求,主要的模式有三种:NOMOUNT.MOUNT.OPEN. 1 ...
- 软件工程_10th weeks
不管是什么原因,都没有在周三24:00前发布博客,赶紧用行动补上~ psp DATE START_TIME END_TIME EVENT TYPE DELTA 5.8 9:00 12:00 论 ...
- hive web界面管理
老版本使用 访问<Hive Server Address>:9999/hwi 1.首先下载对应版本的src文件,本机使用apache-hive-1.2.2-src.tar.gz 2.解压缩 ...
- HTML5 & auto download image
HTML5 & auto download image https://www.sitepoint.com/new-html5-attributes-hyperlinks-download-m ...
- QAU 17校赛 J题 剪丝带(完全背包变形)
题意: 剪一段丝带,对于剪完后的每一段丝带长度必须是a,b,c 输入丝带的长度 n 和 a b c 输出一个整数,代表最多能剪成多少段 样例输入 5 5 3 2 7 5 5 2 样例输出 2 ...
- Threed.sleep是不会释放锁,而wait是释放锁的(对象锁)
实战分析 一直都说,Threed.sleep是不会释放锁,而wait是释放锁的(对象锁),现理论上来分析一下啊. v package thread.concurrent; public class D ...
- 自学Linux Shell12.7-控制循环break、continue命令
点击返回 自学Linux命令行与Shell脚本之路 12.7-控制循环break.continue命令 break命令.break命令用于跳出循环,使用break可以跳出任何类型的循环:for.whi ...