ASP.NET Core ExceptionFilterAttribute Access Controller

With ASP.Net Core 2, how can you access the Controller instance that ExceptionFilterAttribute applies to?

Is there a better way to get general β€œbasic” properties and methods of a controller, etc. Now in Core? For example, put it at a higher level, for example, Startup?

Before Core, in MVC 4, I would do something like this:

/// <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();
    }
}
+4
source share
1 answer

HttpContextin ASP.Net, the Core contains a Itemstype property IDictionary<object, object>for sharing data within the request scope. This is exactly what you need to cover your case. Here is an example 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();
        }
    }
}
+1
source

Source: https://habr.com/ru/post/1691081/


All Articles