Inietti il ​​servizio nel filtro azione

Sto cercando di iniettare un servizio nel mio filtro azione, ma non sto ottenendo il servizio richiesto iniettato nel costruttore. Ecco cosa ho:

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"); } } } 

E sto decorando il mio controller in questo modo:

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

Startup.cs

 services.AddScoped(); 

Usando questi articoli come riferimento:

Filtri di azione di base ASP.NET

Filtri di azione, filtri di servizio e filtri di tipo in ASP.NET 5 e MVC 6

Utilizzo del filtro come un filtro di servizio

Poiché il filtro verrà utilizzato come ServiceType , deve essere registrato con il framework IoC. Se i filtri azione sono stati utilizzati direttamente, questo non sarebbe richiesto.

Startup.cs

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

I filtri personalizzati vengono aggiunti al metodo del controller MVC e alla class controller utilizzando l’attributo ServiceFilter modo:

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

C’erano altri esempi di

  • Utilizzo del filtro come filtro globale

  • Utilizzo del filtro con controller di base

  • Usando il filtro con un ordine

Dai un’occhiata, provali e vedi se questo risolve il tuo problema.

Spero che questo ti aiuti.

Filtri globali

È necessario implementare IFilterFactory :

 public class AuthorizationFilterFactory : IFilterFactory { public bool IsReusable => false; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { // manually find and inject necessary dependencies. var context = (IMyContext)serviceProvider.GetService(typeof(IMyContext)); return new AuthorizationFilter(context); } } 

Nella class di Startup invece di registrare un filtro vero, si registra la fabbrica di filtri:

 services.AddMvc(options => { options.Filters.Add(new AuthorizationFilterFactory()); }); 

Un altro modo per risolvere questo problema. Puoi ottenere il tuo servizio tramite Context come nel seguente codice:

 public override void OnActionExecuting(ActionExecutingContext context) { _sessionService = context.HttpContext.RequestServices.GetService(); if (_sessionService.LoggedInUser == null) { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; context.Result = new JsonResult("Unauthorized"); } } 

Si noti che è necessario registrare questo servizio in Startup.cs

 services.AddTransient(); 

Dopo aver letto questo articolo ASP.NET Core – Real-World ASP.NET Core MVC Filters (agosto 2016) l’ ho implementato in questo modo:

In Starup.cs / ConfigureServices:

 services.AddScoped(); 

In MyFilterAttribute.cs:

 public class MyFilterAttribute : TypeFilterAttribute { public MyFilterAttribute() : base(typeof (MyFilterAttributeImpl)) { } private class MyFilterAttributeImpl : IActionFilter { private readonly MyService _sv; public MyFilterAttributeImpl(MyService sv) { _sv = sv; } public void OnActionExecuting(ActionExecutingContext context) { _sv.MyServiceMethod1(); } public void OnActionExecuted(ActionExecutedContext context) { _sv.MyServiceMethod2(); } } } 

In MyFooController.cs:

 [MyFilter] public IActionResult MyAction() { } 

Modifica: il passaggio di argomenti come [MyFilter("Something")] può essere eseguito utilizzando la proprietà Arguments della class TypeFilterAttribute: Come si aggiunge un parametro a un filtro azione in asp.net? (Il codice di rboe mostra anche come iniettare le cose (allo stesso modo))