hyde hyde - 4 months ago 341
C# Question

ASP.Net Core (MVC 6) - Inject service into Action Filter

I am trying to inject a service into my action filter but I am not getting the required service injected through the constructor. Here is what I have:

public class EnsureUserLoggedIn : ActionFilterAttribute
{
private readonly ISessionService _sessionService;

public EnsureUserLoggedIn()
{
// I was unable able to remove the default ctor
// because of compilation error while using the
// attribute in my controller
}

public EnsureUserLoggedIn(ISessionService sessionService)
{
_sessionService = sessionService;
}

public override void OnActionExecuting(ActionExecutingContext context)
{
// Problem: _sessionService is null here
if (_sessionService.LoggedInUser == null)
{
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Result = new JsonResult("Unauthorized");
}
}
}


And I am decorating my controller like so:

[Route("api/issues"), EnsureUserLoggedIn]
public class IssueController : Controller
{
}


Startup.cs

services.AddScoped<ISessionService, SessionService>();

Answer

Using these articles as reference:

ASP.NET Core 1.0 Action Filters

Action filters, service filters and type filters in ASP.NET 5 and MVC 6

Using the filter as a ServiceFilter

Because the filter will be used as a ServiceType, it needs to be registered with the framework IoC. If the action filters were used directly, this would not be required.

Startup.cs

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc();

    services.AddScoped<ISessionService, SessionService>();
    services.AddScoped<EnsureUserLoggedIn>();

    ...
}

Custom filters are added to the MVC controller method and the controller class using the ServiceFilter attribute like so:

[ServiceFilter(typeof(EnsureUserLoggedIn))]
[Route("api/issues")]
public class IssueController : Controller {
    // GET: api/issues
    [HttpGet]
    [ServiceFilter(typeof(EnsureUserLoggedIn))]
    public IEnumerable<string> Get(){...}
}

There were other examples of

  • Using the filter as a global filter

  • Using the filter with base controllers

  • Using the filter with an order

Take a look, give them a try and see if that resolves your issue.

Hope this helps.