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异常处理的更多相关文章

  1. webapi框架搭建系列博客

    webapi框架搭建系列博客 webapi框架搭建-创建项目(一) webapi框架搭建-创建项目(二)-以iis为部署环境的配置 webapi框架搭建-创建项目(三)-webapi owin web ...

  2. webapi框架搭建-依赖注入之autofac

    前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...

  3. webapi框架搭建-创建项目(三)-webapi owin

    上一篇:创建项目(二) 在上一篇里,我们已经创建好了webapi应用,并已经部署到iis里,本篇讲如何用owin自宿主或是iis宿主来部署webapi应用. owin介绍 传统的asp.net网站只能 ...

  4. webapi框架搭建-创建项目(二)-以iis为部署环境的配置

    上篇:webapi快速框架搭建-创建项目(一) 在"创建项目(一)"这一篇里已经创建了一个空的项目,但项目上什么都没有,本篇描述如何将webapi配置成部署在iis上. 步骤 用n ...

  5. webapi框架搭建-日志管理log4net

    前言 本篇讲怎么在前几篇已经创建好的项目里加上日志处理机制,我们采用Log4net技术.跟多的log4net技术的细节请查阅log4net的官网. log4net官网:http://logging.a ...

  6. webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制

    webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...

  7. webapi框架搭建-安全机制(三)-简单的基于角色的权限控制

    webapi框架搭建系列博客 上一篇已经完成了“身份验证”,如果只是想简单的实现基于角色的权限管理,我们基本上不用写代码,微软已经提供了authorize特性,直接用就行. Authorize特性的使 ...

  8. webapi框架搭建-安全机制(二)-身份验证

    webapi框架搭建系列博客 身份验证(authentication)的责任是识别出http请求者的身份,除此之外尽量不要管其它的事.webapi的authentication我用authentica ...

  9. webapi框架搭建-安全机制(一)

    本系列博客链接:webapi框架搭建系列博客 前言 webapi接口是开放给外部使用的,包括接口的地址,传参的规范,还有返回结果的说明.正因为接口的开放性,使得接口的安全很重要.试想一下,用抓包工具( ...

随机推荐

  1. Java实现小学四则运算练习系统(UI)

    github项目地址 :https://github.com/feser-xuan/Arithmetic_test3_UI 小伙伴的博客链接:http://www.cnblogs.com/fukang ...

  2. JavaScript中给onclick绑定事件后return false遇到的问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Java 修饰符顺序问题

    What is a reasonable order of Java modifiers (abstract, final, public, static, etc.)? http://stackov ...

  4. 自己站点的nginx 配置信息

    user www www; worker_processes auto; error_log /home/wwwlogs/nginx_error.log crit; pid /usr/local/ng ...

  5. QQ互联登录提示redirect uri is illegal(100010)完美解决方法

    大概2015年3月低,腾讯QQ互联开发平台调整了有关QQ登录应用回调地址填写规则,用来修复QQ登录过程因回调地址的漏洞可能导致存在的安全问题. 博主接触这块较多,但也是四月才了解此事,从4月起,所有新 ...

  6. Bootstrap插件概述

    前面的话 Bootstrap除了包含丰富的Web组件之外,如下拉菜单.按钮组.导航.分页等,还包括一些JavaScript的插件.插件为 Bootstrap 的组件赋予了“生命”.Bootstrap的 ...

  7. __add__运行过程

  8. MySQL Binlog详解

    MySQL Binlog详解 Mysql的binlog日志作用是用来记录mysql内部增删改查等对mysql数据库有更新的内容的记录(对数据库的改动),对数据库的查询select或show等不会被bi ...

  9. BZOJ2277[Poi2011]Strongbox——数论

    题目描述 Byteasar is a famous safe-cracker, who renounced his criminal activity and got into testing and ...

  10. POJ3258-River Hopscotch-二分答案

    一条河里有一串石头,给出石头间的间距,让你去掉m个石头,使最短间距最大. 二分答案,对于每一种mid,判断要不要删除这块石头.然后逼近答案. #include <cstdio> #incl ...