Kjensen
Kjensen

Reputation: 12374

ASP.Net Core WebApi - storing values from ActionFilter to access in controller

In an ASP.Net Core WebApp I want to use an ActionFilter and send information from the ActionFilter to the controller it is applied to.

MVC

For MVC I can do this

ActionFilter

    public class TenantActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //Using some sneaky logic to determine current tenant from domain, not important for this example
            int tenantId = 1;
            Controller controller = (Controller)context.Controller;
            controller.ViewData["TenantId"] = tenantId;
        }
        public void OnActionExecuted(ActionExecutedContext context) { }
    }

Controller

    public class TestController : Controller
    {
        [ServiceFilter(typeof(TenantActionFilter))]
        public IActionResult Index()
        {
            int tenantId = ViewData["TenantId"];
            return View(tenantId);
        }
    }

It works and I can pass data back to the controller via ViewData - great.

WebApi

I want to do the same for WebApi Controllers.

The actionFilter itself can be applied, runs etc - but I cannot write to ViewData, because WebAPI inherits from ControllerBase - not from Controller (like MVC).

Question

How can I push data from my ActionFilter back to the calling ControllerBase, similar to MVC?

Notes

Upvotes: 2

Views: 2420

Answers (1)

Kjensen
Kjensen

Reputation: 12374

...So I found the answer when I was almost done writing the question, so here goes...

The answer is the HttpContext.Items collection

ActionFilter

    public class TenantActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            int tenantId = 1;
            var controller = (ControllerBase)context.Controller;
            controller.HttpContext.Items.Add("TenantId", tenantId);
        }
        public void OnActionExecuted(ActionExecutedContext context) { }
    }

Controller

    public class TestApiController : ControllerBase
    {
        [ServiceFilter(typeof(TenantActionFilter))]
        public SomeClass Get()
        {
            int tenantId;
            if (!int.TryParse(HttpContext.Items["TenantId"].ToString(), out tenantId))
            {
                tenantId = -1;
            }
            return new SomeClass();
        }
    }

Upvotes: 5

Related Questions