我正在测试一个MVC 6 Web Api,并希望实现登录到一个全局错误处理程序.只要保证没有错误就会退出系统而不记录.我创建了一个ExceptionFilterAttribute,并在启动时将其全局添加:
public class AppExceptionFilterAttribute : ExceptionFilterAttribute { public override void OnException(ExceptionContext context) { //Notice pulling from HttpContext Application Svcs -- don't like that var loggerFactory = (ILoggerFactory)context.HttpContext.ApplicationServices.GetService(typeof (ILoggerFactory)); var logger = loggerFactory.Create("MyWeb.Web.Api"); logger.WriteError(2,"Error Occurred",context.Exception); context.Result = new JsonResult( new { context.Exception.Message,context.Exception.StackTrace }); } }
现在在启动时,我添加了这个过滤器:
services.Configure<MvcOptions>(options => { options.Filters.Add(new AppExceptionFilterAttribute()); });
这一切似乎是一种暴力…有更好的方式来到这里使用MVC 6?
我不喜欢的东西,或者不了解这种方法:
>不喜欢从http上下文拉DI
>没有关于控制器发生错误的上下文(也许我可以通过某种方式从上下文得到它).
我可以想到的另一个选择是拥有一个基本控制器,它接受所有控制器继承的ILoggerFactory.
想知道是否有某种诊断中间件允许插入日志记录?
@R_502_323@
你的问题有2部分. 1)DI可注射过滤器2)全局错误处理.
关于#1:您可以使用ServiceFilterAttribute用于此目的.
例:
//Modify your filter to be like this to get the logger factory DI injectable. public class AppExceptionFilterAttribute : ExceptionFilterAttribute { private readonly ILogger _logger; public AppExceptionFilterAttribute(ILoggerFactory loggerfactory) { _logger = loggerFactory.CreateLogger<AppExceptionFilterAttribute>(); } public override void OnException(ExceptionContext context) { //... } }
//Register your filter as a service (Note this filter need not be an attribute as such) services.AddTransient<AppExceptionFilterAttribute>();
//On the controller/action where you want to apply this filter,//decorate them like [ServiceFilter(typeof(AppExceptionFilterAttribute))] public class HomeController : Controller { .... }
您应该能够从传递的ExceptionContext获取控制器的详细信息.
关于#2:从你以前的帖子看起来像是在使用ExceptionHandlerMiddleware(source& extension source)…如何使用它?…有关的一些信息:
>这个中间件是通用的,适用于任何中间件在它之后注册了所有任何概念,如控制器/动作信息是特定于MVC的,该中间件不会知道.>这个中间件不处理格式化程序写入异常.你可以编写自己的缓冲中间件,您可以在其中修改响应身体成为缓冲流(MemoryStream)并让MVC层写回应.在格式化程序写入异常的情况下,您可以抓住它并发送一个500错误响应与细节.