[英]Access Controller from ExceptionFilterAttribute in ASP.NET Core
With ASP.Net Core 2, how could you get access to the Controller instance that an ExceptionFilterAttribute is applied to?使用 ASP.Net Core 2,您如何访问应用了 ExceptionFilterAttribute 的 Controller 实例?
Is there a better way to acheive shared "base" controller properties and methods, etc. now in Core?现在在 Core 中是否有更好的方法来实现共享的“基础”controller 属性和方法等? Such as putting it in a higher level like Startup?比如像Startup那样放到更高的层级?
Before Core, In MVC 4, I would do something like this:在 Core 之前,在 MVC 4 中,我会做这样的事情:
/// <summary>
/// Base controller, shared by all WebAPI controllers for tracking and shared properties.
/// </summary>
[ApiTracking]
[ApiException]
public class BaseApiController : ApiController
{
private Common.Models.Tracking _Tracking = null;
public Common.Models.Tracking Tracking
{
get
{
if(_Tracking == null)
_Tracking = new Common.Models.Tracking();
return _Tracking;
}
}
//... other shared properties...
}
/// <summary>
/// Error handler for webapi calls. Adds tracking to base controller.
/// </summary>
public class ApiExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext cntxt)
{
BaseApiController ctrl = cntxt.ActionContext.ControllerContext.Controller as BaseApiController;
if (ctrl != null)
ctrl.Tracking.Exception(cntxt.Exception, true);
base.OnException(actionExecutedContext);
}
}
/// <summary>
/// Intercepts all requests to inject tracking detail and call tracking.save.
/// </summary>
public class ApiTrackingAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext cntxt)
{
//...add info to tracking
}
public override void OnActionExecuted(HttpActionExecutedContext cntxt)
{
BaseApiController ctrl = cntxt.ActionContext.ControllerContext.Controller as BaseApiController;
if (ctrl != null)
ctrl.Tracking.Save();
}
}
HttpContext
in ASP.Net Core contains Items
property of IDictionary<object, object>
type for sharing the data within the scope of the request. ASP.Net Core中的HttpContext
包含IDictionary<object, object>
类的Items
属性,用于在请求范围内共享数据。 It's exactly what you need for covering your case. 这正是您覆盖案件所需要的。 Here is a sample implementation: 这是一个示例实现:
public class ApiExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var items = context.HttpContext.Items;
if (items.ContainsKey("Tracking"))
{
Tracking tracking = (Tracking)items["Tracking"];
tracking.Exception(context.Exception, true);
}
base.OnException(context);
}
}
public class ApiTrackingAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var tracking = new Tracking();
//...add info to tracking
context.HttpContext.Items.Add("Tracking", tracking);
}
public override void OnActionExecuted(ActionExecutedContext context)
{
var items = context.HttpContext.Items;
if (items.ContainsKey("Tracking"))
{
Tracking tracking = (Tracking) items["Tracking"];
tracking.Save();
}
}
}
If you're using .NET 6 or later, check out my answer here .如果您使用的是 .NET 6 或更高版本,请在此处查看我的回答。 I provided a sample on how to get access to the controller using a combination of Microsoft.AspNetCore.Mvc.Filters.IActionFilter and Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter.我提供了一个示例,说明如何结合使用 Microsoft.AspNetCore.Mvc.Filters.IActionFilter 和 Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter 来访问 controller。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.