Filtri in ASP.NET CoreFilters in ASP.NET Core

Di Kirk Larkin, Rick Anderson, Tom Dykstra e Steve SmithBy Kirk Larkin, Rick Anderson, Tom Dykstra, and Steve Smith

I filtri in ASP.NET Core consentono l'esecuzione del codice prima o dopo fasi specifiche della pipeline di elaborazione della richiesta.Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

I filtri predefiniti gestiscono attività, ad esempio:Built-in filters handle tasks such as:

  • Autorizzazione (impedire l'accesso alle risorse per cui un utente non è autorizzato).Authorization (preventing access to resources a user isn't authorized for).
  • Memorizzazione nella cache delle risposte (blocco della pipeline delle richieste per restituire una risposta memorizzata nella cache).Response caching (short-circuiting the request pipeline to return a cached response).

I filtri personalizzati possono essere creati per gestire problemi relativi a più settori.Custom filters can be created to handle cross-cutting concerns. Esempi di problematiche trasversali includono la gestione degli errori, la memorizzazione nella cache, la configurazione, l'autorizzazione e la registrazione.Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. I filtri evitano la duplicazione del codice.Filters avoid duplicating code. Ad esempio, un filtro eccezioni per la gestione degli errori potrebbe consolidare la gestione degli errori.For example, an error handling exception filter could consolidate error handling.

Questo documento si applica a Razor Pages, controller API e controller con visualizzazioni.This document applies to Razor Pages, API controllers, and controllers with views.

Visualizzare o scaricare un esempio (procedura per il download).View or download sample (how to download).

Funzionamento dei filtriHow filters work

I filtri vengono eseguiti all'interno della pipeline di chiamata di azioni ASP.NET Core, talvolta definita pipeline di filtro.Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. La pipeline di filtro viene eseguita dopo che ASP.NET Core ha selezionato l'azione da eseguire.The filter pipeline runs after ASP.NET Core selects the action to execute.

La richiesta viene elaborata tramite altro middleware, il middleware di routing, la selezione dell'azione e la pipeline di chiamata di azioni ASP.NET Core.

Tipi di filtroFilter types

Ogni tipo di filtro viene eseguito in una fase diversa della pipeline di filtro:Each filter type is executed at a different stage in the filter pipeline:

  • I filtri di autorizzazione vengono eseguiti per primi e consentono di determinare se l'utente è autorizzato per la richiesta.Authorization filters run first and are used to determine whether the user is authorized for the request. I filtri di autorizzazione causano il corto circuito della pipeline se la richiesta non è autorizzata.Authorization filters short-circuit the pipeline if the request is unauthorized.

  • Filtri di risorse:Resource filters:

    • Vengono eseguiti dopo l'autorizzazione.Run after authorization.
    • OnResourceExecuting può eseguire codice prima del resto della pipeline di filtro.OnResourceExecuting can run code before the rest of the filter pipeline. Ad esempio, OnResourceExecuting può eseguire codice prima dell'associazione di modelli.For example, OnResourceExecuting can run code before model binding.
    • OnResourceExecuted può eseguire codice dopo che il resto della pipeline è stato completato.OnResourceExecuted can run code after the rest of the pipeline has completed.
  • I filtri azione possono eseguire codice immediatamente prima e dopo la chiamata di un metodo di azione singolo.Action filters can run code immediately before and after an individual action method is called. Possono essere usati per modificare gli argomenti passati a un'azione e il risultato restituito dall'azione.They can be used to manipulate the arguments passed into an action and the result returned from the action. I filtri di azione non sono supportati in Razor Pages.Action filters are not supported in Razor Pages.

  • I filtri eccezioni vengono usati per applicare i criteri globali a eccezioni non gestite che si verificano prima che qualsiasi elemento sia stato scritto nel corpo della risposta.Exception filters are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body.

  • I filtri risultato possono eseguire codice immediatamente prima e dopo l'esecuzione di risultati di azioni singole.Result filters can run code immediately before and after the execution of individual action results. Vengono eseguiti solo quando il metodo di azione è stato eseguito correttamente.They run only when the action method has executed successfully. Sono utili per la logica che deve racchiudere l'esecuzione del formattatore o di una vista.They are useful for logic that must surround view or formatter execution.

Il diagramma seguente illustra come interagiscono i tipi di filtro nella pipeline di filtro.The following diagram shows how filter types interact in the filter pipeline.

La richiesta passa attraverso i filtri autorizzazione, i filtri risorse, l'associazione di modelli, i filtri azione, l'esecuzione dell'azione e la conversione del risultato dell'azione, i filtri eccezioni, i filtri risultato e l'esecuzione del risultato.

ImplementazioneImplementation

I filtri supportano sia implementazioni sincrone che asincrone tramite definizioni di interfaccia diverse.Filters support both synchronous and asynchronous implementations through different interface definitions.

I filtri sincroni possono eseguire codice prima (On-Stage-Executing) e dopo (On-Stage-Executed) la relativa fase della pipeline.Synchronous filters can run code before (On-Stage-Executing) and after (On-Stage-Executed) their pipeline stage. La chiamata di OnActionExecuting, ad esempio, avviene prima della chiamata del metodo di azione.For example, OnActionExecuting is called before the action method is called. La chiamata di OnActionExecuted avviene dopo l'esecuzione del metodo di azione.OnActionExecuted is called after the action method returns.

public class MySampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

I filtri asincroni definiscono un metodo On-Stage-ExecutionAsync:Asynchronous filters define an On-Stage-ExecutionAsync method:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        // Do something before the action executes.

        // next() calls the action method.
        var resultContext = await next();
        // resultContext.Result is set.
        // Do something after the action executes.
    }
}

Nel codice precedente SampleAsyncActionFilter ha un oggetto ActionExecutionDelegate (next) che esegue il metodo di azione.In the preceding code, the SampleAsyncActionFilter has an ActionExecutionDelegate (next) that executes the action method. Ognuno dei metodi On-Stage-ExecutionAsync accetta un oggetto FilterType-ExecutionDelegate che esegue la fase della pipeline del filtro.Each of the On-Stage-ExecutionAsync methods take a FilterType-ExecutionDelegate that executes the filter's pipeline stage.

Fasi di filtro multipleMultiple filter stages

È possibile implementare interfacce per più fasi di filtro in una singola classe.Interfaces for multiple filter stages can be implemented in a single class. Ad esempio, la classe ActionFilterAttribute implementa IActionFilter, IResultFilter e i relativi equivalenti asincroni.For example, the ActionFilterAttribute class implements IActionFilter, IResultFilter, and their async equivalents.

Implementare la versione sincrona oppure la versione asincrona di un'interfaccia di filtro, non entrambe.Implement either the synchronous or the async version of a filter interface, not both. Il runtime controlla per prima cosa se il filtro implementa l'interfaccia asincrona e, in tal caso, la chiama.The runtime checks first to see if the filter implements the async interface, and if so, it calls that. In caso contrario, chiama i metodi dell'interfaccia sincrona.If not, it calls the synchronous interface's method(s). Se in una classe sono implementate entrambe le interfacce, sincrona e asincrona, viene chiamato solo il metodo asincrono.If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. Quando si usano classi astratte come ActionFilterAttribute eseguire l'override solo dei metodi sincroni o del metodo asincrono per ogni tipo di filtro.When using abstract classes like ActionFilterAttribute override only the synchronous methods or the async method for each filter type.

Attributi filtro predefinitiBuilt-in filter attributes

ASP.NET Core include filtri predefiniti basati su attributi che è possibile impostare come sottoclasse e personalizzare.ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. Il filtro dei risultati seguente, ad esempio, aggiunge un'intestazione alla risposta:For example, the following result filter adds a header to the response:

public class AddHeaderAttribute : ResultFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public AddHeaderAttribute(string name, string value)
    {
        _name = name;
        _value = value;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add( _name, new string[] { _value });
        base.OnResultExecuting(context);
    }
}

Gli attributi consentono ai filtri di accettare argomenti, come illustrato nell'esempio precedente.Attributes allow filters to accept arguments, as shown in the preceding example. Applicare AddHeaderAttribute a un controller o a un metodo di azione e specificare il nome e il valore dell'intestazione HTTP:Apply the AddHeaderAttribute to a controller or action method and specify the name and value of the HTTP header:

[AddHeader("Author", "Joe Smith")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

Molte delle interfacce del filtro presentano attributi corrispondenti che possono essere usati come classi di base per implementazioni personalizzate.Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

Attributi dei filtri:Filter attributes:

Ambiti dei filtri e ordine di esecuzioneFilter scopes and order of execution

È possibile aggiungere un filtro alla pipeline in uno dei tre ambiti:A filter can be added to the pipeline at one of three scopes:

  • Usando un attributo di un'azione.Using an attribute on an action.
  • Usando un attributo di un controller.Using an attribute on a controller.
  • A livello globale per tutti i controller e le azioni come illustrato nel codice seguente:Globally for all controllers and actions as shown in the following code:
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
            "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Il codice precedente aggiunge tre filtri a livello globale tramite la raccolta MvcOptions.Filters.The preceding code adds three filters globally using the MvcOptions.Filters collection.

Ordine di esecuzione predefinitoDefault order of execution

Quando sono presenti più filtri per una particolare fase della pipeline, l'ambito determina l'ordine di esecuzione predefinito dei filtri.When there are multiple filters for a particular stage of the pipeline, scope determines the default order of filter execution. I filtri globali racchiudono i filtri di classe, che a loro volta racchiudono i filtri dei metodi.Global filters surround class filters, which in turn surround method filters.

Come risultato dell'annidamento dei filtri, il codice after dei filtri viene eseguito in ordine inverso rispetto al codice before.As a result of filter nesting, the after code of filters runs in the reverse order of the before code. Sequenza di filtro:The filter sequence:

  • Codice before dei filtri globali.The before code of global filters.
    • Codice before dei filtri del controller.The before code of controller filters.
      • Codice before dei filtri del metodo di azione.The before code of action method filters.
      • Codice after dei filtri del metodo di azione.The after code of action method filters.
    • Codice after dei filtri del controller.The after code of controller filters.
  • Codice after dei filtri globali.The after code of global filters.

L'esempio seguente illustra l'ordine in cui i metodi dei filtri vengono chiamati per i filtri di azione sincroni.The following example that illustrates the order in which filter methods are called for synchronous action filters.

SequenceSequence Ambito del filtroFilter scope Filter - metodoFilter method
11 GlobalGlobal OnActionExecuting
22 ControllerController OnActionExecuting
33 MetodoMethod OnActionExecuting
44 MetodoMethod OnActionExecuted
55 ControllerController OnActionExecuted
66 GlobalGlobal OnActionExecuted

Questa sequenza mostra che:This sequence shows:

  • Il filtro del metodo è annidato all'interno del filtro del controller.The method filter is nested within the controller filter.
  • Il filtro del controller è annidato all'interno del filtro globale.The controller filter is nested within the global filter.

Filtri a livello di controller e pagina RazorController and Razor Page level filters

Ogni controller che eredita dalla classe di base Controller include i metodi Controller.OnActionExecuting, Controller.OnActionExecutionAsync e Controller.OnActionExecuted OnActionExecuted.Every controller that inherits from the Controller base class includes Controller.OnActionExecuting, Controller.OnActionExecutionAsync, and Controller.OnActionExecuted OnActionExecuted methods. Questi metodi:These methods:

  • Eseguono il wrapping dei filtri che vengono eseguiti per una determinata azione.Wrap the filters that run for a given action.
  • La chiamata di OnActionExecuting avviene prima di qualsiasi filtro dell'azione.OnActionExecuting is called before any of the action's filters.
  • La chiamata di OnActionExecuted avviene dopo tutti i filtri dell'azione.OnActionExecuted is called after all of the action filters.
  • La chiamata di OnActionExecutionAsync avviene prima di qualsiasi filtro dell'azione.OnActionExecutionAsync is called before any of the action's filters. Il codice del filtro dopo next viene eseguito dopo il metodo di azione.Code in the filter after next runs after the action method.

Ad esempio, l'applicazione di MySampleActionFilter nell'esempio scaricato avviene a livello globale all'avvio.For example, in the download sample, MySampleActionFilter is applied globally in startup.

TestController:The TestController:

  • Applica il SampleActionFilterAttribute ([SampleActionFilter]) all'azione di FilterTest2.Applies the SampleActionFilterAttribute ([SampleActionFilter]) to the FilterTest2 action.
  • Esegue l'override di OnActionExecuting e OnActionExecuted.Overrides OnActionExecuting and OnActionExecuted.
public class TestController : Controller
{
    [SampleActionFilter]
    public IActionResult FilterTest2()
    {
        return Content($"From FilterTest2");
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        base.OnActionExecuted(context);
    }
}

Passando a https://localhost:5001/Test/FilterTest2, viene eseguito il codice seguente:Navigating to https://localhost:5001/Test/FilterTest2 runs the following code:

  • TestController.OnActionExecuting
    • MySampleActionFilter.OnActionExecuting
      • SampleActionFilterAttribute.OnActionExecuting
        • TestController.FilterTest2
      • SampleActionFilterAttribute.OnActionExecuted
    • MySampleActionFilter.OnActionExecuted
  • TestController.OnActionExecuted

Per Razor Pages, vedere Implementare i filtri di Razor Pages eseguendo l'override dei metodi di filtro.For Razor Pages, see Implement Razor Page filters by overriding filter methods.

Override dell'ordine predefinitoOverriding the default order

È possibile eseguire l'override della sequenza di esecuzione predefinita implementando IOrderedFilter.The default sequence of execution can be overridden by implementing IOrderedFilter. IOrderedFilter espone la proprietà Order, che ha la precedenza sull'ambito per determinare l'ordine di esecuzione.IOrderedFilter exposes the Order property that takes precedence over scope to determine the order of execution. Un filtro con un valore di Order inferiore:A filter with a lower Order value:

  • Esegue il codice before prima di quello di un filtro con un valore di Order più alto.Runs the before code before that of a filter with a higher value of Order.
  • Esegue il codice after dopo quello di un filtro con un valore di Order più alto.Runs the after code after that of a filter with a higher Order value.

La proprietà Order può essere impostata con un parametro del costruttore:The Order property can be set with a constructor parameter:

[MyFilter(Name = "Controller Level Attribute", Order=1)]

Prendere in considerazione gli stessi tre filtri di azione illustrati nell'esempio precedente.Consider the same 3 action filters shown in the preceding example. Se la proprietà Order del controller e dei filtri globali è impostata, rispettivamente, su 1 e su 2, l'ordine di esecuzione viene invertito.If the Order property of the controller and global filters is set to 1 and 2 respectively, the order of execution is reversed.

SequenceSequence Ambito del filtroFilter scope ProprietàOrderOrder property Filter - metodoFilter method
11 MetodoMethod 00 OnActionExecuting
22 ControllerController 11 OnActionExecuting
33 GlobalGlobal 22 OnActionExecuting
44 GlobalGlobal 22 OnActionExecuted
55 ControllerController 11 OnActionExecuted
66 MetodoMethod 00 OnActionExecuted

La proprietà Order ha la precedenza sull'ambito nel determinare l'ordine di esecuzione dei filtri.The Order property overrides scope when determining the order in which filters run. I filtri vengono ordinati prima in base all'ordine, poi viene usato l'ambito per interrompere i collegamenti.Filters are sorted first by order, then scope is used to break ties. Tutti i filtri predefiniti implementano IOrderedFilter e impostano il valore predefinito di Order su 0.All of the built-in filters implement IOrderedFilter and set the default Order value to 0. Per i filtri predefiniti, l'ambito determina l'ordine, a meno che non si imposti Order su un valore diverso da zero.For built-in filters, scope determines order unless Order is set to a non-zero value.

Annullamento e corto circuitoCancellation and short-circuiting

È possibile causare il corto circuito della pipeline di filtro impostando la proprietà Result sul parametro ResourceExecutingContext fornito al metodo di filtro.The filter pipeline can be short-circuited by setting the Result property on the ResourceExecutingContext parameter provided to the filter method. Ad esempio, il filtro di risorse seguente impedisce l'esecuzione del resto della pipeline:For instance, the following Resource filter prevents the rest of the pipeline from executing:

public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.Result = new ContentResult()
        {
            Content = "Resource unavailable - header not set."
        };
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

Nel codice seguente sia il filtro ShortCircuitingResourceFilter che il filtro AddHeader hanno come destinazione il metodo di azione SomeResource.In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. ShortCircuitingResourceFilter:The ShortCircuitingResourceFilter:

  • Viene eseguito per primo perché è un filtro risorsa e AddHeader è un filtro azione.Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
  • Blocca il resto della pipeline.Short-circuits the rest of the pipeline.

Pertanto il filtro AddHeader non viene mai eseguito per l'azione SomeResource.Therefore the AddHeader filter never runs for the SomeResource action. Questo comportamento sarebbe lo stesso se entrambi i filtri venissero applicati a livello di metodo di azione, a condizione che il filtro ShortCircuitingResourceFilter venga eseguito prima.This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. ShortCircuitingResourceFilter viene eseguito per primo per il tipo di filtro o per l'uso esplicito della proprietà Order.The ShortCircuitingResourceFilter runs first because of its filter type, or by explicit use of Order property.

[AddHeader("Author", "Joe Smith")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

Inserimento di dipendenzeDependency injection

È possibile aggiungere filtri per tipo o per istanza.Filters can be added by type or by instance. Se viene aggiunta un'istanza, tale istanza viene usata per ogni richiesta.If an instance is added, that instance is used for every request. Se viene aggiunto un tipo, il filtro è attivato dal tipo.If a type is added, it's type-activated. Un filtro attivato dal tipo comporta:A type-activated filter means:

  • La creazione di un'istanza per ogni richiesta.An instance is created for each request.
  • Il popolamento di tutte le dipendenze del costruttore tramite inserimento delle dipendenze.Any constructor dependencies are populated by dependency injection (DI).

I filtri implementati come attributi e aggiunti direttamente alle classi controller o ai metodi di azione non possono avere dipendenze costruttore specificate dall'inserimento di dipendenze.Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). Le dipendenze del costruttore non possono essere fornite tramite inserimento delle dipendenze in quanto:Constructor dependencies cannot be provided by DI because:

  • I parametri del costruttore devono essere forniti agli attributi nella posizione in cui vengono applicati.Attributes must have their constructor parameters supplied where they're applied.
  • Questa è una limitazione del funzionamento degli attributi.This is a limitation of how attributes work.

I filtri seguenti supportano le dipendenze del costruttore fornite dall'inserimento delle dipendenze:The following filters support constructor dependencies provided from DI:

I filtri precedenti possono essere applicati a un controller o a un metodo di azione:The preceding filters can be applied to a controller or action method:

I logger sono disponibili tramite l'inserimento delle dipendenze.Loggers are available from DI. Evitare tuttavia di creare e usare filtri esclusivamente per scopi di registrazione.However, avoid creating and using filters purely for logging purposes. La funzionalità di registrazione del framework predefinita in genere fornisce il necessario per la registrazione.The built-in framework logging typically provides what's needed for logging. La registrazione aggiunta ai filtri:Logging added to filters:

  • Deve concentrarsi su problemi del dominio di business o comportamenti specifici del filtro.Should focus on business domain concerns or behavior specific to the filter.
  • Non deve registrare azioni o altri eventi del framework.Should not log actions or other framework events. I filtri predefiniti registrano azioni ed eventi del framework.The built in filters log actions and framework events.

ServiceFilterAttributeServiceFilterAttribute

I tipi di implementazione del filtro di servizi sono registrati in ConfigureServices.Service filter implementation types are registered in ConfigureServices. ServiceFilterAttribute recupera un'istanza del filtro dall'inserimento di dipendenze.A ServiceFilterAttribute retrieves an instance of the filter from DI.

Il codice seguente illustra AddHeaderResultServiceFilter:The following code shows the AddHeaderResultServiceFilter:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation("Header added: {HeaderName}", headerName);
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
    }
}

Nel codice seguente l'oggetto AddHeaderResultServiceFilter viene aggiunto al contenitore di inserimento delle dipendenze:In the following code, AddHeaderResultServiceFilter is added to the DI container:

public void ConfigureServices(IServiceCollection services)
{
    // Add service filters.
    services.AddScoped<AddHeaderResultServiceFilter>();
    services.AddScoped<SampleActionFilterAttribute>();

    services.AddMvc(options =>
    {
        options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
            "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Nel codice seguente l'attributo ServiceFilter recupera un'istanza del filtro AddHeaderResultServiceFilter dall'inserimento delle dipendenze:In the following code, the ServiceFilter attribute retrieves an instance of the AddHeaderResultServiceFilter filter from DI:

[ServiceFilter(typeof(AddHeaderResultServiceFilter))]
public IActionResult Index()
{
    return View();
}

Quando si usa l'impostazione ServiceFilterAttribute, ServiceFilterAttribute.IsReusable:When using ServiceFilterAttribute, setting ServiceFilterAttribute.IsReusable:

  • Indica che l'istanza del filtro può essere riutilizzata all'esterno dell'ambito della richiesta in cui è stata creata.Provides a hint that the filter instance may be reused outside of the request scope it was created within. Il runtime di ASP.NET Core non garantisce:The ASP.NET Core runtime doesn't guarantee:

    • Che venga creata una singola istanza del filtro.That a single instance of the filter will be created.
    • Che il filtro non verrà richiesto di nuovo dal contenitore di inserimento delle dipendenze in un momento successivo.The filter will not be re-requested from the DI container at some later point.
  • Non si deve usare con un filtro che dipende da servizi con una durata diversa da singleton.Should not be used with a filter that depends on services with a lifetime other than singleton.

ServiceFilterAttribute implementa IFilterFactory.ServiceFilterAttribute implements IFilterFactory. IFilterFactory espone il metodo CreateInstance per creare un'istanza IFilterMetadata.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance carica il tipo specificato dall'inserimento delle dipendenze.CreateInstance loads the specified type from DI.

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttribute è simile a ServiceFilterAttribute, ma il relativo tipo non viene risolto direttamente dal contenitore dell'inserimento di dipendenze.TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. Viene creata un'istanza del tipo tramite Microsoft.Extensions.DependencyInjection.ObjectFactory.It instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

Poiché i tipi TypeFilterAttribute non vengono risolti direttamente dal contenitore di inserimento delle dipendenze:Because TypeFilterAttribute types aren't resolved directly from the DI container:

  • Non è necessario che i tipi a cui viene fatto riferimento tramite TypeFilterAttribute siano registrati nel contenitore di inserimento delle dipendenze.Types that are referenced using the TypeFilterAttribute don't need to be registered with the DI container. Le loro dipendenze vengono soddisfatte dal contenitore di inserimento delle dipendenze.They do have their dependencies fulfilled by the DI container.
  • In via facoltativa, TypeFilterAttribute può anche accettare gli argomenti del costruttore per il tipo.TypeFilterAttribute can optionally accept constructor arguments for the type.

Quando si usa l'impostazione TypeFilterAttribute, TypeFilterAttribute.IsReusable:When using TypeFilterAttribute, setting TypeFilterAttribute.IsReusable:

  • Indica che l'istanza del filtro può essere riutilizzata all'esterno dell'ambito della richiesta in cui è stata creata.Provides hint that the filter instance may be reused outside of the request scope it was created within. Il runtime di ASP.NET Core non fornisce alcuna garanzia che venga creata una singola istanza del filtro.The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created.

  • Non si deve usare con un filtro che dipende da servizi con una durata diversa da singleton.Should not be used with a filter that depends on services with a lifetime other than singleton.

L'esempio seguente illustra come passare argomenti a un tipo usando TypeFilterAttribute:The following example shows how to pass arguments to a type using TypeFilterAttribute:

[TypeFilter(typeof(LogConstantFilter),
    Arguments = new object[] { "Method 'Hi' called" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}
public class LogConstantFilter : IActionFilter
{
    private readonly string _value;
    private readonly ILogger<LogConstantFilter> _logger;

    public LogConstantFilter(string value, ILogger<LogConstantFilter> logger)
    {
        _logger = logger;
        _value = value;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation(_value);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    { }
}

Filtri di autorizzazioneAuthorization filters

I filtri di autorizzazione:Authorization filters:

  • Sono i primi filtri a essere eseguiti nella pipeline di filtro.Are the first filters run in the filter pipeline.
  • Controllano l'accesso ai metodi di azione.Control access to action methods.
  • Dispongono di un metodo precedente, ma non di un metodo successivo.Have a before method, but no after method.

I filtri di autorizzazione personalizzati richiedono un framework di autorizzazione personalizzato.Custom authorization filters require a custom authorization framework. È preferibile configurare criteri di autorizzazione o scrivere criteri di autorizzazione personalizzati piuttosto che scrivere un filtro personalizzato.Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. Il filtro di autorizzazione predefinito:The built-in authorization filter:

  • Chiama il sistema di autorizzazione.Calls the authorization system.
  • Non autorizza le richieste.Does not authorize requests.

Non generare eccezioni nei filtri di autorizzazione:Do not throw exceptions within authorization filters:

  • L'eccezione non verrà gestita.The exception will not be handled.
  • I filtri di eccezione non gestiranno l'eccezione.Exception filters will not handle the exception.

È consigliabile emettere una richiesta di verifica in caso di eccezione in un filtro di autorizzazione.Consider issuing a challenge when an exception occurs in an authorization filter.

Altre informazioni sull'autorizzazione.Learn more about Authorization.

Filtri risorseResource filters

I filtri di risorse:Resource filters:

I filtri di risorse sono utili per causare il corto circuito della maggior parte della pipeline.Resource filters are useful to short-circuit most of the pipeline. Un filtro di memorizzazione nella cache può, ad esempio, evitare il resto della pipeline in caso di riscontro nella cache.For example, a caching filter can avoid the rest of the pipeline on a cache hit.

Esempi di filtri di risorse:Resource filter examples:

Filtri azioniAction filters

Importante

I filtri azione non si applicano a Razor Pages.Action filters do not apply to Razor Pages. Razor Pages supporta IPageFilter e IAsyncPageFilter.Razor Pages supports IPageFilter and IAsyncPageFilter . Per ulteriori informazioni, vedere Metodi di filtro per Razor Pages.For more information, see Filter methods for Razor Pages.

I filtri di azione:Action filters:

Il codice seguente mostra un filtro di azione di esempio:The following code shows a sample action filter:

public class MySampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

La classe ActionExecutingContext specifica le proprietà seguenti:The ActionExecutingContext provides the following properties:

  • ActionArguments: consente di leggere gli input per un metodo di azione.ActionArguments - enables the inputs to an action method be read.
  • Controller: consente di modificare l'istanza del controller.Controller - enables manipulating the controller instance.
  • Result: l'impostazione di Result causa il corto circuito del metodo di azione e dei filtri di azione successivi.Result - setting Result short-circuits execution of the action method and subsequent action filters.

La generazione di un'eccezione in un metodo di azione:Throwing an exception in an action method:

  • Impedisce l'esecuzione dei filtri successivi.Prevents running of subsequent filters.
  • A differenza dell'impostazione di Result, è considerata un errore anziché un risultato positivo.Unlike setting Result, is treated as a failure instead of a successful result.

La classe ActionExecutedContext specifica Controller e Result oltre alle proprietà seguenti:The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled: true se un altro file ha causato il corto circuito dell'azione.Canceled - True if the action execution was short-circuited by another filter.

  • Exception: non Null se l'azione o un filtro di azione eseguito in precedenza ha generato un'eccezione.Exception - Non-null if the action or a previously run action filter threw an exception. Se si imposta questa proprietà su Null:Setting this property to null:

    • L'eccezione viene gestita in modo efficace.Effectively handles the exception.
    • L'oggetto Result viene eseguito come se fosse stato restituito dal metodo di azione.Result is executed as if it was returned from the action method.

Per un oggetto IAsyncActionFilter, una chiamata a ActionExecutionDelegate:For an IAsyncActionFilter, a call to the ActionExecutionDelegate:

  • Esegue qualsiasi filtro azione successivo e il metodo di azione.Executes any subsequent action filters and the action method.
  • Restituisce un valore ActionExecutedContext.Returns ActionExecutedContext.

Per causare il corto circuito, assegnare Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result a un'istanza del risultato e non chiamare next (ActionExecutionDelegate).To short-circuit, assign Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result to a result instance and don't call next (the ActionExecutionDelegate).

Il framework fornisce un oggetto ActionFilterAttribute astratto che è possibile impostare come sottoclasse.The framework provides an abstract ActionFilterAttribute that can be subclassed.

Il filtro di azione OnActionExecuting può essere usato per:The OnActionExecuting action filter can be used to:

  • Convalidare lo stato del modello.Validate model state.
  • Restituire un errore se lo stato non è valido.Return an error if the state is invalid.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }

Il metodo OnActionExecuted viene eseguito dopo il metodo di azione:The OnActionExecuted method runs after the action method:

  • È possibile visualizzare e modificare i risultati dell'azione tramite la proprietà Result.And can see and manipulate the results of the action through the Result property.

  • L'impostazione di Canceled è true se un altro filtro ha causato il corto circuito dell'esecuzione dell'azione.Canceled is set to true if the action execution was short-circuited by another filter.

  • L'impostazione di Exception è un valore non Null se l'azione o un filtro di azione successivo ha generato un'eccezione.Exception is set to a non-null value if the action or a subsequent action filter threw an exception. Impostazione di Exception su null:Setting Exception to null:

    • Gestisce un'eccezione in modo efficace.Effectively handles an exception.
    • L'oggetto ActionExecutedContext.Result viene eseguito come se fosse stato restituito normalmente dal metodo di azione.ActionExecutedContext.Result is executed as if it were returned normally from the action method.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }


    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var result = context.Result;
        // Do something with Result.
        if (context.Canceled == true)
        {
            // Action execution was short-circuited by another filter.
        }

        if(context.Exception != null)
        {
            // Exception thrown by action or action filter.
            // Set to null to handle the exception.
            context.Exception = null;
        }
        base.OnActionExecuted(context);
    }
}

Filtri eccezioniException filters

Filtri eccezioni:Exception filters:

Il filtro di eccezione di esempio seguente usa una visualizzazione degli errori personalizzata per mostrare i dettagli sulle eccezioni che si verificano quando l'app è in fase di sviluppo:The following sample exception filter uses a custom error view to display details about exceptions that occur when the app is in development:

public class CustomExceptionFilter : IExceptionFilter
{
    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

    public CustomExceptionFilter(
        IHostingEnvironment hostingEnvironment,
        IModelMetadataProvider modelMetadataProvider)
    {
        _hostingEnvironment = hostingEnvironment;
        _modelMetadataProvider = modelMetadataProvider;
    }

    public void OnException(ExceptionContext context)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            return;
        }
        var result = new ViewResult {ViewName = "CustomError"};
        result.ViewData = new ViewDataDictionary(_modelMetadataProvider,
                                                    context.ModelState);
        result.ViewData.Add("Exception", context.Exception);
        // TODO: Pass additional detailed data via ViewData
        context.Result = result;
    }
}

Filtri eccezioni:Exception filters:

  • Non dispone di eventi precedenti o successivi.Don't have before and after events.
  • Implementano OnException o OnExceptionAsync.Implement OnException or OnExceptionAsync.
  • Gestiscono le eccezioni non gestite che si verificano nella creazione di un controller o una pagina Razor, nell'associazione di modelli, nei filtri di azione o nei metodi di azione.Handle unhandled exceptions that occur in Razor Page or controller creation, model binding, action filters, or action methods.
  • Non rilevano le eccezioni che si verificano nei filtri di risorse, nei filtri dei risultati o nell'esecuzione dei risultati MVC.Do not catch exceptions that occur in resource filters, result filters, or MVC result execution.

Per gestire un'eccezione, impostare la proprietà ExceptionHandled su true o scrivere una risposta.To handle an exception, set the ExceptionHandled property to true or write a response. In questo modo si arresta la propagazione dell'eccezione.This stops propagation of the exception. Un filtro di eccezione non può modificare un'eccezione in una "operazione riuscita".An exception filter can't turn an exception into a "success". Questa operazione può essere eseguita solo tramite un filtro di azione.Only an action filter can do that.

Filtri eccezioni:Exception filters:

  • Sono ideali per intercettare le eccezioni che si verificano nelle azioni.Are good for trapping exceptions that occur within actions.
  • Non sono flessibili quanto il middleware di gestione degli errori.Are not as flexible as error handling middleware.

Scegliere il middleware per la gestione delle eccezioni.Prefer middleware for exception handling. Usare i filtri di eccezione solo quando la gestione degli errori varia in base al metodo di azione chiamato.Use exception filters only where error handling differs based on which action method is called. Un'app può ad esempio avere metodi di azione sia per gli endpoint API che per le visualizzazioni/HTML.For example, an app might have action methods for both API endpoints and for views/HTML. Gli endpoint dell'API possono restituire informazioni sull'errore come JSON, mentre le azioni basate sulla visualizzazione possono restituire una pagina di errore in formato HTML.The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

Filtri risultatoResult filters

I filtri dei risultati:Result filters:

IResultFilter e IAsyncResultFilterIResultFilter and IAsyncResultFilter

Il codice seguente illustra un filtro dei risultati che aggiunge un'intestazione HTTP:The following code shows a result filter that adds an HTTP header:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation("Header added: {HeaderName}", headerName);
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
    }
}

Il tipo di risultato eseguito dipende dall'azione.The kind of result being executed depends on the action. Un'azione che restituisce una visualizzazione include tutte le elaborazioni Razor come parte dell'elemento ViewResult eseguito.An action returning a view would include all razor processing as part of the ViewResult being executed. Un metodo API può eseguire la serializzazione in quanto parte dell'esecuzione del risultato.An API method might perform some serialization as part of the execution of the result. Altre informazioni sui risultati dell'azione.Learn more about action results.

I filtri dei risultati vengono eseguiti solo quando un filtro azione o azione produce un risultato di azione.Result filters are only executed when an action or action filter produces an action result. I filtri dei risultati non vengono eseguiti nei casi seguenti:Result filters are not executed when:

  • Un filtro di autorizzazione o un filtro risorse cortocircui la pipeline.An authorization filter or resource filter short-circuits the pipeline.
  • Un filtro di eccezione non gestisca un'eccezione producendo un risultato dell'azione.An exception filter handles an exception by producing an action result.

Il metodo Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting può causare il corto circuito dell'esecuzione del risultato dell'azione e dei filtri dei risultati successivi se si imposta Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel su true.The Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting method can short-circuit execution of the action result and subsequent result filters by setting Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel to true. In caso di corto circuito, scrivere nell'oggetto risposta per evitare di generare una risposta vuota.Write to the response object when short-circuiting to avoid generating an empty response. La generazione di un'eccezione in IResultFilter.OnResultExecuting:Throwing an exception in IResultFilter.OnResultExecuting will:

  • Impedisce l'esecuzione del risultato dell'azione e dei filtri successivi.Prevent execution of the action result and subsequent filters.
  • È considerata un errore anziché un risultato positivo.Be treated as a failure instead of a successful result.

Quando viene eseguito il metodo Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted, è probabile che la risposta sia già stata inviata al client.When the Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted method runs, the response has likely already been sent to the client. Se la risposta è già stata inviata al client, non è possibile modificarla ulteriormente.If the response has already been sent to the client, it cannot be changed further.

L'impostazione di ResultExecutedContext.Canceled è true se un altro filtro ha causato il corto circuito dell'esecuzione del risultato dell'azione.ResultExecutedContext.Canceled is set to true if the action result execution was short-circuited by another filter.

L'impostazione di ResultExecutedContext.Exception è un valore non Null se il risultato dell'azione o un filtro dei risultati successivo ha generato un'eccezione.ResultExecutedContext.Exception is set to a non-null value if the action result or a subsequent result filter threw an exception. Se si imposta Exception su Null l'eccezione viene gestita in modo efficace e si evita che venga generata nuovamente da ASP.NET Core in un punto successivo della pipeline.Setting Exception to null effectively handles an exception and prevents the exception from being rethrown by ASP.NET Core later in the pipeline. Non c'è alcun modo affidabile per scrivere i dati in una risposta quando si gestisce un'eccezione in un filtro dei risultati.There is no reliable way to write data to a response when handling an exception in a result filter. Se le intestazioni sono state scaricate nel client quando il risultato di un'azione genera un'eccezione, non c'è alcun meccanismo affidabile per inviare un codice di errore.If the headers have been flushed to the client when an action result throws an exception, there's no reliable mechanism to send a failure code.

Per un oggetto IAsyncResultFilter, una chiamata a await next in ResultExecutionDelegate esegue tutti i filtri dei risultati successivi e il risultato dell'azione.For an IAsyncResultFilter, a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. Per causare il corto circuito, impostare ResultExecutingContext.Cancel su true e non chiamare ResultExecutionDelegate:To short-circuit, set ResultExecutingContext.Cancel to true and don't call the ResultExecutionDelegate:

public class MyAsyncResponseFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context,
                                             ResultExecutionDelegate next)
    {
        if (!(context.Result is EmptyResult))
        {
            await next();
        }
        else
        {
            context.Cancel = true;
        }

    }
}

Il framework fornisce un oggetto ResultFilterAttribute astratto che è possibile impostare come sottoclasse.The framework provides an abstract ResultFilterAttribute that can be subclassed. La classe AddHeaderAttribute illustrata in precedenza è un esempio di un attributo di filtro dei risultati.The AddHeaderAttribute class shown previously is an example of a result filter attribute.

IAlwaysRunResultFilter e IAsyncAlwaysRunResultFilterIAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter

Le interfacce IAlwaysRunResultFilter e IAsyncAlwaysRunResultFilter dichiarano un'implementazione di IResultFilter eseguita per tutti i risultati dell'azione.The IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter interfaces declare an IResultFilter implementation that runs for all action results. Sono inclusi i risultati dell'azione prodotti da:This includes action results produced by:

  • Filtri di autorizzazione e filtri delle risorse che interessano il cortocircuito.Authorization filters and resource filters that short-circuit.
  • Filtri eccezioni.Exception filters.

Ad esempio, il filtro seguente viene eseguito sempre e imposta un risultato dell'azione (ObjectResult) con un codice di stato 422 Entità non elaborabile quando la negoziazione del contenuto ha esito negativo:For example, the following filter always runs and sets an action result (ObjectResult) with a 422 Unprocessable Entity status code when content negotiation fails:

public class UnprocessableResultFilter : Attribute, IAlwaysRunResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is StatusCodeResult statusCodeResult &&
            statusCodeResult.StatusCode == 415)
        {
            context.Result = new ObjectResult("Can't process this!")
            {
                StatusCode = 422,
            };
        }
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
    }
}

IFilterFactoryIFilterFactory

IFilterFactory implementa IFilterMetadata.IFilterFactory implements IFilterMetadata. Pertanto, un'istanza di IFilterFactory può essere usata come un'istanza di IFilterMetadata in un punto qualsiasi della pipeline filtro.Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. Quando il runtime si prepara per richiamare il filtro, cerca di eseguirne il cast a un oggetto IFilterFactory.When the runtime prepares to invoke the filter, it attempts to cast it to an IFilterFactory. Se l'esecuzione del cast ha esito positivo, viene chiamato il metodo CreateInstance per creare l'istanza di IFilterMetadata richiamata.If that cast succeeds, the CreateInstance method is called to create the IFilterMetadata instance that is invoked. In questo modo viene specificata una struttura flessibile, poiché non è necessario impostare in modo esplicito la pipeline filtro all'avvio dell'app.This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.

Un altro approccio alla creazione di filtri consiste nell'implementare IFilterFactory usando implementazioni dell'attributo personalizzate:IFilterFactory can be implemented using custom attribute implementations as another approach to creating filters:

public class AddHeaderWithFactoryAttribute : Attribute, IFilterFactory
{
    // Implement IFilterFactory
    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        return new InternalAddHeaderFilter();
    }

    private class InternalAddHeaderFilter : IResultFilter
    {
        public void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(
                "Internal", new string[] { "My header" });
        }

        public void OnResultExecuted(ResultExecutedContext context)
        {
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Il codice precedente può essere testato eseguendo l'esempio scaricato:The preceding code can be tested by running the download sample:

  • Richiamare gli strumenti di sviluppo F12.Invoke the F12 developer tools.
  • Passare a https://localhost:5001/Sample/HeaderWithFactory.Navigate to https://localhost:5001/Sample/HeaderWithFactory.

Gli strumenti di sviluppo F12 visualizzano le intestazioni di risposta seguenti aggiunte dal codice di esempio:The F12 developer tools display the following response headers added by the sample code:

  • author: Joe Smithauthor: Joe Smith
  • globaladdheader: Result filter added to MvcOptions.Filtersglobaladdheader: Result filter added to MvcOptions.Filters
  • internal: My headerinternal: My header

Il codice precedente crea l'intestazione di risposta internal: My header.The preceding code creates the internal: My header response header.

Implementazione di IFilterFactory in un attributoIFilterFactory implemented on an attribute

I filtri che implementano IFilterFactory sono utili per i filtri che:Filters that implement IFilterFactory are useful for filters that:

  • Non richiedono il passaggio di parametri.Don't require passing parameters.
  • Hanno dipendenze del costruttore che devono essere soddisfatte dall'inserimento delle dipendenze.Have constructor dependencies that need to be filled by DI.

TypeFilterAttribute implementa IFilterFactory.TypeFilterAttribute implements IFilterFactory. IFilterFactory espone il metodo CreateInstance per creare un'istanza IFilterMetadata.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance carica il tipo specificato dal contenitore di inserimento delle dipendenze.CreateInstance loads the specified type from the services container (DI).

public class SampleActionFilterAttribute : TypeFilterAttribute
{
    public SampleActionFilterAttribute():base(typeof(SampleActionFilterImpl))
    {
    }

    private class SampleActionFilterImpl : IActionFilter
    {
        private readonly ILogger _logger;
        public SampleActionFilterImpl(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            _logger.LogInformation("Business action starting...");
            // perform some business logic work

        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // perform some business logic work
            _logger.LogInformation("Business action completed.");
        }
    }
}

Il codice seguente illustra tre approcci all'applicazione di [SampleActionFilter]:The following code shows three approaches to applying the [SampleActionFilter]:

[SampleActionFilter]
public IActionResult FilterTest()
{
    return Content($"From FilterTest");
}

[TypeFilter(typeof(SampleActionFilterAttribute))]
public IActionResult TypeFilterTest()
{
    return Content($"From ServiceFilterTest");
}

// ServiceFilter must be registered in ConfigureServices or
// System.InvalidOperationException: No service for type '<filter>' has been registered.
// Is thrown.
[ServiceFilter(typeof(SampleActionFilterAttribute))]
public IActionResult ServiceFilterTest()
{
    return Content($"From ServiceFilterTest");
}

Nel codice precedente la decorazione del metodo con [SampleActionFilter] è l'approccio da preferire per applicare SampleActionFilter.In the preceding code, decorating the method with [SampleActionFilter] is the preferred approach to applying the SampleActionFilter.

Uso di middleware nella pipeline filtroUsing middleware in the filter pipeline

I filtri risorse funzionano come middleware in quanto racchiudono l'esecuzione di tutto ciò che viene dopo nella pipeline.Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. I filtri sono diversi dal middleware in quanto fanno parte del runtime di ASP.NET Core, quindi hanno accesso al contesto e ai costrutti di ASP.NET Core.But filters differ from middleware in that they're part of the ASP.NET Core runtime, which means that they have access to ASP.NET Core context and constructs.

Per usare il middleware come filtro, creare un tipo con un metodo Configure che specifica il middleware da inserire nella pipeline di filtro.To use middleware as a filter, create a type with a Configure method that specifies the middleware to inject into the filter pipeline. L'esempio seguente usa il middleware di localizzazione per stabilire le impostazioni cultura correnti per una richiesta:The following example uses the localization middleware to establish the current culture for a request:

public class LocalizationPipeline
{
    public void Configure(IApplicationBuilder applicationBuilder)
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("fr")
        };

        var options = new RequestLocalizationOptions
        {

            DefaultRequestCulture = new RequestCulture(culture: "en-US", 
                                                     uiCulture: "en-US"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };
        options.RequestCultureProviders = new[] 
            { new RouteDataRequestCultureProvider() { Options = options } };

        applicationBuilder.UseRequestLocalization(options);
    }
}

Usare MiddlewareFilterAttribute per eseguire il middleware:Use the MiddlewareFilterAttribute to run the middleware:

[Route("{culture}/[controller]/[action]")]
[MiddlewareFilter(typeof(LocalizationPipeline))]
public IActionResult CultureFromRouteData()
{
    return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},"
        + $"CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
}

I filtri middleware vengono eseguiti nella stessa fase della pipeline filtro come filtri risorse, prima dell'associazione di modelli e dopo il resto della pipeline.Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.

Azioni successiveNext actions