从零开始搭建.NET Core 2.0 API(学习笔记一)
从零开始搭建.net core 2.0 api(学习笔记一)
一、 vs 2017 新建一个项目 选择asp.net core web应用程序,再选择web api,选择asp.net core 2.0版本
二、 添加api帮助页面 api项目添加 nuget nswag.aspnetcore 引用, 然后在添加nswag设置
运行项目 http://localhost:prot/swagger 即可打开帮助页。
public void configure(iapplicationbuilder app, ihostingenvironment env) { if (env.isdevelopment()) { app.usedeveloperexceptionpage(); app.usebrowserlink(); } else { app.useexceptionhandler("/home/error"); } app.usestaticfiles(); app.useswaggerui(typeof(startup).gettypeinfo().assembly, settings => { settings.generatorsettings.defaultpropertynamehandling = propertynamehandling.camelcase; }); app.usemvc(route => { route.maproute(name: "default", template: "{controller=home}/{action=get}/{id?}"); }); }
三、 startup 类configureservices方法中,添加配置中心初始化;配置中心统一管理配置,便于维护
public iserviceprovider configureservices(iservicecollection services) { confighelper.init(configuration["configzookeeperaddress"], configuration["confignodepath"]); services.addsingleton<ilogwrite, logwrite>(); services.addmvc(options => { options.filters.add<authorizationfilter>(); options.filters.add<exceptionfilter>(); options.filters.add<performancelogfilter>(); }); var builder = new containerbuilder();//实例化 autofac 容器 builder.populate(services); // todo: 这里添加其他需要注入类的注册 applicationcontainer = builder.build(); return new autofacserviceprovider(applicationcontainer); }
四、添加一个基础设置项目,添加一个日志接口 ilogwrite,一个记录日志实现类 logwrite 在startup 类configureservices方法中添加日志 ioc
因为日志拦截器和异常拦截器会用到日志记录需要注入 所以日志在addmvc()前面添加,autofac配置不能在 addmvc前面,所以这里用.net core的ioc容器,后面autofac会接管容器。
services.addsingleton<ilogwrite, logwrite>();
五、filter 添加三个类分别是
a authorizationfilter 权限过滤器
b exceptionfilter 异常过滤器
c performancelogfilter 性能日志过滤器
exceptionfilter 、performancelogfilter 分别定义构造函数,注入日志依赖。
public exceptionfilter(ilogwrite logwrite) { _logwrite = logwrite; } public performancelogfilter(ilogwrite logwrite) { _logwrite = logwrite; }
过滤器必须添加在 startup类configureservices的services.addmvc()中
services.addmvc(options => { options.filters.add<authorizationfilter>(); options.filters.add<exceptionfilter>(); options.filters.add<performancelogfilter>(); });
六、action参数读取,为了在异常过滤器、性能日志过滤器中,读取参数需要在权限过滤器中添加下面两行代码
public class authorizationfilter : iauthorizationfilter { public void onauthorization(authorizationfiltercontext context) { httprequest request = context.httpcontext.request; request.enablerewind(); request.body.position = 0; } }
七、性能日志过滤器 performancelogfilter 继承 iactionfilter,实现两个接口
onactionexecuting 在调用操作方法之前发生
onactionexecuted 在调用操作方法之后发生
a 在方法 onactionexecuting中 实例化一个 stopwatch 用于记录方法开支执行时间
把stopwatch 实力加入 httpcontext.items 中,便于在 onactionexecuted 获取。
b 读取action请求参数, 放入 httpcontext.items 中, 不知道为什么onactionexecuted 去不到参数
/// <summary> /// 在调用操作方法之前发生。 /// </summary> /// <param name="context"></param> public void onactionexecuting(actionexecutingcontext context) {
// if (skiplogging(context)) return; var watch = new stopwatch(); context.httpcontext.items[confighelper.httprequeststopwatcher] = watch; var paramenters = context.actionarguments.count==0?string.empty:context.actionarguments.serialize(); context.httpcontext.items[confighelper.filteractionarguments] = paramenters; watch.start(); }
onactionexecuting 中增加了性能日志开关,如果关闭直接返回,不创建stopwatch,
在onactionexecuted中回去到的stopwatch是null 则直接返回(也可以用性能日志开关做判断),不处理后续。
如果controll、action添加了nolog特性,则不记录性能日志
private static bool skiplogging(actionexecutingcontext actioncontext) { if (!confighelper.isperformancelog) return true; return actioncontext.actiondescriptor.gettype().getcustomattributes(typeof(nologattribute), false).any() || actioncontext.controller.gettype().getcustomattributes(typeof(nologattribute), false).any(); }
/// <summary> /// 忽略性能日志记录特性 /// </summary> [attributeusage(attributetargets.method | attributetargets.class, inherited = true)] public class nologattribute : attribute { }
八、异常过滤器
/// <summary> /// 异常拦截器 /// </summary> public class exceptionfilter : iexceptionfilter { ilogwrite _logwrite; public exceptionfilter(ilogwrite logwrite) { _logwrite = logwrite; } /// <summary> /// /// </summary> /// <param name="actionexecutedcontext"></param> /// <param name="cancellationtoken"></param> /// <returns></returns> public void onexception(exceptioncontext context) { bizresult<bool> biz; var paramenters = context.httpcontext.items[confighelper.filteractionarguments].tostring(); try { biz = new bizresult<bool>(false, (int)b2cbizcode.exception, context.exception.message); if (context.exception.innerexception != null) biz.sysmessage += ":" + context.exception.innerexception.message; if (confighelper.isperformancelog) { var watch = context.httpcontext.items[confighelper.httprequeststopwatcher] as stopwatch; watch?.stop(); var name = context.actiondescriptor.gettype().getproperty("actionname").getvalue(context.actiondescriptor).tostring(); _logwrite.infoasync(new { createtime = datetime.now, method = name, timespan = watch.elapsed, issuccess = false, content = paramenters, code = ((b2cbizcode)biz.businesscode).tostring(), message = biz.businessmessage }.serialize()); } } catch (exception ex) { biz = new bizresult<bool>(false, (int)b2cbizcode.exception, ex.message); } context.result = new applicationerrorresult(biz); _logwrite?.errorasync($"链接访问出错:{context.httpcontext.request.path}", context.httpcontext.request.method, this.gettype().name, context.exception, paramenters); return; } } public class applicationerrorresult : objectresult { public applicationerrorresult(object value) : base(value) { statuscode = (int)httpstatuscode.internalservererror; } }
九 、添加autofac,autofac比.net core自带的 ioc更好用。 nugetapi 项目中添加autofac.configuration、autofac.extensions.dependencyinjection 两个引用 然后 configureservices方法中添加ioc容器
public iserviceprovider configureservices(iservicecollection services) { confighelper.init(configuration["configzookeeperaddress"], configuration["confignodepath"]); services.addsingleton<ilogwrite, logwrite>(); services.addmvc(options => { options.filters.add<authorizationfilter>(); options.filters.add<exceptionfilter>(); options.filters.add<performancelogfilter>(); }); var builder = new containerbuilder();//实例化 autofac 容器 builder.populate(services); // todo: 这里添加其他需要注入类的注册 applicationcontainer = builder.build(); return new autofacserviceprovider(applicationcontainer); }
至此.net core api的 拦截器、配置管理、日志、ioc 设置已完成。
public iserviceprovider configureservices(iservicecollection services) { confighelper.init(configuration["configzookeeperaddress"], configuration["confignodepath"]); services.addsingleton<ilogwrite, logwrite>();
services.addmvc(options => { options.filters.add<authorizationfilter>(); options.filters.add<exceptionfilter>(); options.filters.add<performancelogfilter>(); });
var builder = new containerbuilder();//实例化 autofac 容器 builder.populate(services);
// todo: 这里添加其他需要注入类的注册
applicationcontainer = builder.build(); return new autofacserviceprovider(applicationcontainer); }
上一篇: RHEL7系统管理之内核管理
推荐阅读
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.3 自动生成实体类
-
CodeFirst从零开始搭建Asp.Net Core2.0网站
-
【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 完善
-
ASP.NET Core 2 学习笔记(十二)REST-Like API
-
【从零开始搭建自己的.NET Core Api框架】(七)授权认证进阶篇
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.2 在框架的基础上利用SqlSugar快速实现CRUD实战篇
-
《ASP.NET Core In Action》读书笔记系列,这是一个手把手的从零开始的教学系列目录
-
Asp.net core 2.0.1 Razor 的使用学习笔记(一)
-
ASP.NET Core 一步步搭建个人网站(5)_Api模拟和网站分析
-
【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证