ASP.NET Core2.2 IExceptionFilter
程序员文章站
2022-06-30 22:54:46
用vs2017建立一个ASP.NET Core Web应用程序并选择MVC框架,自动生成了 Startup的类,并配置了错误处理方式: if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExcept ......
用vs2017建立一个asp.net core web应用程序并选择mvc框架,自动生成了 startup的类,并配置了错误处理方式:
if (env.isdevelopment()) { app.usedeveloperexceptionpage(); } else { app.useexceptionhandler("/home/error"); app.usehsts(); }
简单讲:
- 开发环境,直接在当前页面显示错误
- 生产环境:跳转到 /home/error页面
而在实际开发和生产过程中,我们需要:
- 开发环境,我们有时候会用到ajax调用,需要快速定位错误(比如alert(....))
- 生产环境:我们需要把错误信息保存起来,当然ajax调用的时候不能直接alert一个/home/error的html给用户
如下面的代码:
action: public iactionresult edit(int id = 0) { if (id == 0) //模拟用户不能修改该id的内容 return notfound("没有操作权限"); if (id == 1) //模拟发生异常了 throw new exception("错误:error desc"); return view(); } /// <summary> /// ajax调用 /// </summary> /// <param name="id"></param> /// <returns></returns> [httppost] public iactionresult save(int id = 0) { if (id == 0) //模拟用户不能修改该id的内容 return notfound("没有操作权限"); if (id == 1) //模拟发生异常了 throw new exception("错误:error desc"); return content(id + datetime.now.tostring()); } view(edit.cshtml) <div class="text-center"> id: <input type="text" id="tid" /> <input type="button" value="save" id="bsave" /> <span id="sresult"></span> </div> @section scripts { <script> $(function () { $("#bsave").click(function () { $.ajax({ type: "post", url: "@url.action("save")", data: { id: $("#tid").val() }, success: function (ret) { $("#sresult").html(ret); }, error: function (xmlhttprequest) { if (xmlhttprequest.responsetext != "") { alert(xmlhttprequest.responsetext); } else alert(xmlhttprequest.status ); } }); }); }); </script> }
ctrl+f5##运行:
好,我们需要保存错误信息,并更友好的提示ajax调用错误。
1.添加一个类
public class filterexception : iexceptionfilter { private readonly ykdbcontext db; private readonly ihostingenvironment _env; public filterexception(ykdbcontext dbcontext, ihostingenvironment env) { db = dbcontext; _env = env; } public void onexception(exceptioncontext context) { if (_env.isdevelopment()) { if (context.httpcontext.request.headers["x-requested-with"] == "xmlhttprequest") { context.httpcontext.response.statuscode = (int)httpstatuscode.internalservererror; string msg = context.exception.message; exception ex = context.exception; while (ex.innerexception != null) { ex = ex.innerexception; msg += ex.message; } context.result = new jsonresult(msg); context.exceptionhandled = true; // 表明异常已处理,客户端可得到正常返回 } } else { string msg = context.exception.message; exception ex = context.exception; while (ex.innerexception != null) { ex = ex.innerexception; msg += ex.message; } //存入db if (context.httpcontext.request.headers["x-requested-with"] == "xmlhttprequest") { context.httpcontext.response.statuscode = (int)httpstatuscode.internalservererror; context.result = new jsonresult("出错了!已经将错误信息发送给开发人员,开发人员将尽快处理。"); context.exceptionhandled = true; } } } }
2.配置服务
在类startup
的方法configureservices
中修改
services.addmvc(options => { options.filters.add<filterexception>(); }) .setcompatibilityversion(compatibilityversion.version_2_2);
依然按##ctrl+f5##运行:
是我们想要的结果吧?!
附:filter里面如何判断controller
是否有apicontroller
属性
bool isapi = context.filters.any(ii => ii.gettype().name == "apicontrollerattribute");