Filtres dans ASP.NET CoreFilters in ASP.NET Core

Par Kirk Larkin, Rick Anderson, Tom Dykstra et Steve SmithBy Kirk Larkin, Rick Anderson, Tom Dykstra, and Steve Smith

Les filtres dans ASP.NET Core permettent d’exécuter du code avant ou après des étapes spécifiques dans le pipeline de traitement des requêtes.Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

Les filtres intégrés gèrent notamment les tâches suivantes :Built-in filters handle tasks such as:

  • Autorisation (empêcher un utilisateur non autorisé d’accéder à des ressources).Authorization (preventing access to resources a user isn't authorized for).
  • Mise en cache des réponses (court-circuitage du pipeline de requêtes pour retourner une réponse mise en cache).Response caching (short-circuiting the request pipeline to return a cached response).

Il est possible de créer des filtres personnalisés pour gérer les problèmes transversaux.Custom filters can be created to handle cross-cutting concerns. Les exemples de problèmes transversaux incluent la gestion des erreurs, la mise en cache, la configuration, l’autorisation et la journalisation.Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Les filtres évitent la duplication de code.Filters avoid duplicating code. Par exemple, un filtre d’exceptions de gestion des erreurs peut servir à consolider la gestion des erreurs.For example, an error handling exception filter could consolidate error handling.

Ce document s’applique aux Razor Pages, aux contrôleurs d’API et aux contrôleurs avec affichages.This document applies to Razor Pages, API controllers, and controllers with views.

Afficher ou télécharger l’échantillon (comment télécharger).View or download sample (how to download).

Fonctionnement des filtresHow filters work

Les filtres s’exécutent dans le pipeline des appels d’action ASP.NET Core, parfois appelé pipeline de filtres.Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. Le pipeline de filtres s’exécute après la sélection par ASP.NET Core de l’action à exécuter.The filter pipeline runs after ASP.NET Core selects the action to execute.

La requête est traitée via un autre intergiciel, un intergiciel de routage, une sélection d’action et le pipeline d’appels d’action ASP.NET Core.

Types de filtresFilter types

Chaque type de filtre est exécuté dans une étape différente du pipeline de filtres :Each filter type is executed at a different stage in the filter pipeline:

  • Les filtres d’autorisations s’exécutent en premier et sont utilisés pour déterminer si l’utilisateur est autorisé pour la requête.Authorization filters run first and are used to determine whether the user is authorized for the request. Les filtres d’autorisations peuvent court-circuiter le pipeline si la requête n’est pas autorisée.Authorization filters short-circuit the pipeline if the request is unauthorized.

  • Filtres de ressources :Resource filters:

    • Exécuter après l’autorisation.Run after authorization.
    • OnResourceExecuting peut exécuter du code avant le reste du pipeline de filtres.OnResourceExecuting can run code before the rest of the filter pipeline. Par exemple, OnResourceExecuting peut exécuter du code avant la liaison de données.For example, OnResourceExecuting can run code before model binding.
    • OnResourceExecuted peut exécuter du code une fois que le reste du pipeline terminé.OnResourceExecuted can run code after the rest of the pipeline has completed.
  • Les filtres d’actions peuvent exécuter du code juste avant et juste après l’appel d’une méthode d’action individuelle.Action filters can run code immediately before and after an individual action method is called. Ils peuvent être utilisés pour manipuler les arguments passés à une action et le résultat retourné depuis l’action.They can be used to manipulate the arguments passed into an action and the result returned from the action. Les filtres d’actions ne sont pas pris en charge dans les Razor Pages.Action filters are not supported in Razor Pages.

  • Les filtres d’exceptions sont utilisés pour appliquer des stratégies globales à des exceptions non gérées qui se produisent avant que des éléments aient été écrits dans le corps de la réponse.Exception filters are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body.

  • Les filtres de résultats peuvent exécuter du code juste avant et juste après l’exécution des résultats d’une action individuelle.Result filters can run code immediately before and after the execution of individual action results. Ils s’exécutent uniquement au terme de l’exécution de la méthode d’action.They run only when the action method has executed successfully. Ils sont utiles pour la logique qui doit entourer l’exécution de la vue ou du formateur.They are useful for logic that must surround view or formatter execution.

Le diagramme suivant montre comment ces types de filtres interagissent dans le pipeline de filtres.The following diagram shows how filter types interact in the filter pipeline.

La requête est traitée à travers les filtres d’autorisations, les filtres de ressources, la liaison de modèle, les filtres d’actions, l’exécution d’actions et la conversion des résultats d’actions, les filtres d’exceptions, les filtres de résultats et l’exécution de résultats.

ImplémentationImplementation

Les filtres prennent en charge les implémentations synchrones et asynchrones via différentes définitions d’interface.Filters support both synchronous and asynchronous implementations through different interface definitions.

Les filtres synchrones peuvent exécuter du code avant (On-Stage-Executing) et après (On-Stage-Executed) leur étape de pipeline.Synchronous filters can run code before (On-Stage-Executing) and after (On-Stage-Executed) their pipeline stage. Par exemple, OnActionExecuting est appelé avant l’appel de la méthode d’action.For example, OnActionExecuting is called before the action method is called. OnActionExecuted est appelé après le retour de la méthode d’action.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.
    }
}

Les filtres asynchrones définissent une méthode 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.
    }
}

Dans le code précédent, le SampleAsyncActionFilter a un ActionExecutionDelegate (next) qui exécute la méthode d’action.In the preceding code, the SampleAsyncActionFilter has an ActionExecutionDelegate (next) that executes the action method. Chacune des méthodes On-Stage-ExecutionAsync prennent un FilterType-ExecutionDelegate qui exécute l’étape de pipeline du filtre.Each of the On-Stage-ExecutionAsync methods take a FilterType-ExecutionDelegate that executes the filter's pipeline stage.

Plusieurs étapes de filtresMultiple filter stages

Vous pouvez implémenter des interfaces pour plusieurs étapes de filtres dans une même classe.Interfaces for multiple filter stages can be implemented in a single class. Par exemple, la classe ActionFilterAttribute implémente IActionFilter, IResultFilter et leurs équivalents asynchrones.For example, the ActionFilterAttribute class implements IActionFilter, IResultFilter, and their async equivalents.

Implémentez la version synchrone ou bien la version asynchrone d’une interface de filtre, mais pas les deux.Implement either the synchronous or the async version of a filter interface, not both. Le runtime vérifie d’abord si le filtre implémente l’interface asynchrone et, le cas échéant, il appelle cette interface.The runtime checks first to see if the filter implements the async interface, and if so, it calls that. Dans le cas contraire, il appelle la ou les méthodes de l’interface synchrone.If not, it calls the synchronous interface's method(s). Si des interfaces synchrones et asynchrones sont implémentées dans une classe, seule la méthode asynchrone est appelée.If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. Quand vous utilisez des classes abstraites comme ActionFilterAttribute, vous devez remplacer seulement les méthodes synchrones ou la méthode asynchrone pour chaque type de filtre.When using abstract classes like ActionFilterAttribute override only the synchronous methods or the async method for each filter type.

Attributs de filtre intégrésBuilt-in filter attributes

ASP.NET Core inclut les filtres intégrés basés sur des attributs que vous pouvez définir dans une sous-classe et personnaliser.ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. Par exemple, le filtre de résultats suivant ajoute un en-tête à la réponse :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);
    }
}

Les attributs autorisent les filtres à accepter des arguments, comme indiqué dans l’exemple ci-dessus.Attributes allow filters to accept arguments, as shown in the preceding example. Appliquez le AddHeaderAttribute à un contrôleur ou une méthode d’action et spécifiez le nom et la valeur de l’en-tête 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.");
    }

Plusieurs des interfaces de filtre ont des attributs correspondants qui peuvent être utilisés comme classes de base pour des implémentations personnalisées.Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

Les attributs de filtre :Filter attributes:

Étendues de filtre et ordre d’exécutionFilter scopes and order of execution

Un filtre peut être ajouté au pipeline à une des trois étendues :A filter can be added to the pipeline at one of three scopes:

  • À l’aide d’un attribut sur une action.Using an attribute on an action.
  • À l’aide d’un attribut sur un contrôleur.Using an attribute on a controller.
  • Dans le monde entier pour tous les contrôleurs et actions, comme indiqué dans le code suivant :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);
}

Le code précédent ajoute trois filtres globalement à l’aide de la collection MvcOptions.Filters.The preceding code adds three filters globally using the MvcOptions.Filters collection.

Ordre d’exécution par défautDefault order of execution

Quand il existe plusieurs filtres pour une étape particulière du pipeline, l’étendue détermine l’ordre par défaut de l’exécution du filtre.When there are multiple filters for a particular stage of the pipeline, scope determines the default order of filter execution. Les filtres globaux entourent les filtres de classe, qui à leur tour entourent les filtres de méthode.Global filters surround class filters, which in turn surround method filters.

En raison de l’imbrication de filtres, le code après des filtres s’exécute dans l’ordre inverse du code avant.As a result of filter nesting, the after code of filters runs in the reverse order of the before code. La séquence de filtre :The filter sequence:

  • Le code avant des filtres globaux.The before code of global filters.
    • Le code avant des filtres du contrôleur.The before code of controller filters.
      • Le code avant des filtres de méthodes d’action.The before code of action method filters.
      • Le code après des filtres de méthodes d’action.The after code of action method filters.
    • Le code après des filtres du contrôleur.The after code of controller filters.
  • Le code après des filtres globaux.The after code of global filters.

Voici un exemple qui illustre l’ordre dans lequel les méthodes de filtre sont appelées pour les filtres d’actions synchrones.The following example that illustrates the order in which filter methods are called for synchronous action filters.

SéquenceSequence Étendue de filtreFilter scope Méthode de filtreFilter method
11 GlobalGlobal OnActionExecuting
22 ContrôleurController OnActionExecuting
33 MéthodeMethod OnActionExecuting
44 MéthodeMethod OnActionExecuted
55 ContrôleurController OnActionExecuted
66 GlobalGlobal OnActionExecuted

Cette séquence montre que :This sequence shows:

  • Le filtre de méthode est imbriqué dans le filtre de contrôleur.The method filter is nested within the controller filter.
  • Le filtre de contrôleur est imbriqué dans le filtre global.The controller filter is nested within the global filter.

Filtres au niveau de contrôleur et de Razor PageController and Razor Page level filters

Chaque contrôleur qui hérite de la classe de base Controller inclut les méthodes Controller.OnActionExecuting, Controller.OnActionExecutionAsync et Controller.OnActionExecuted OnActionExecuted.Every controller that inherits from the Controller base class includes Controller.OnActionExecuting, Controller.OnActionExecutionAsync, and Controller.OnActionExecuted OnActionExecuted methods. Ces méthodes :These methods:

  • Incluent dans un wrapper les filtres qui s’exécutent pour une action donnée.Wrap the filters that run for a given action.
  • OnActionExecuting est appelé avant tous les filtres de l’action.OnActionExecuting is called before any of the action's filters.
  • OnActionExecuted est appelé après tous les filtres d’actions.OnActionExecuted is called after all of the action filters.
  • OnActionExecutionAsync est appelé avant tous les filtres de l’action.OnActionExecutionAsync is called before any of the action's filters. Le code dans le filtre après next s’exécute après la méthode d’action.Code in the filter after next runs after the action method.

Par exemple, dans l’échantillon à télécharger, MySampleActionFilter est appliqué globalement au démarrage.For example, in the download sample, MySampleActionFilter is applied globally in startup.

Voici le TestController :The TestController:

  • Applique le SampleActionFilterAttribute ([SampleActionFilter]) pour l’action FilterTest2 :Applies the SampleActionFilterAttribute ([SampleActionFilter]) to the FilterTest2 action:
  • Remplace OnActionExecuting et 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);
    }
}

La navigation vers https://localhost:5001/Test/FilterTest2 exécute le code suivant :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

Pour Razor Pages, consultez Implémenter des filtres Razor Page en remplaçant les méthodes de filtre.For Razor Pages, see Implement Razor Page filters by overriding filter methods.

Remplacement de l’ordre par défautOverriding the default order

Vous pouvez remplacer la séquence d’exécution par défaut en implémentant IOrderedFilter.The default sequence of execution can be overridden by implementing IOrderedFilter. IOrderedFilter expose la propriété Order qui est prioritaire sur l’étendue afin de déterminer l’ordre d’exécution.IOrderedFilter exposes the Order property that takes precedence over scope to determine the order of execution. Un filtre avec une valeur Order inférieure :A filter with a lower Order value:

  • Exécute le code avant avant celui d’un filtre avec une valeur supérieure à Order.Runs the before code before that of a filter with a higher value of Order.
  • Exécute le code après après celui d’un filtre avec une valeur Order supérieure.Runs the after code after that of a filter with a higher Order value.

La propriété Order peut être définie avec un paramètre de constructeur :The Order property can be set with a constructor parameter:

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

Prenez en compte les mêmes 3 filtres d’actions indiqués dans l’exemple précédent.Consider the same 3 action filters shown in the preceding example. Si la propriété Order du contrôleur et les filtres globaux sont définis sur 1 et 2 respectivement, l’ordre d’exécution est inversé.If the Order property of the controller and global filters is set to 1 and 2 respectively, the order of execution is reversed.

SéquenceSequence Étendue de filtreFilter scope PropriétéOrder Order property Méthode de filtreFilter method
11 MéthodeMethod 00 OnActionExecuting
22 ContrôleurController 11 OnActionExecuting
33 GlobalGlobal 22 OnActionExecuting
44 GlobalGlobal 22 OnActionExecuted
55 ContrôleurController 11 OnActionExecuted
66 MéthodeMethod 00 OnActionExecuted

La propriété Order remplace l’étendue lors de la détermination de l’ordre dans lequel les filtres s’exécutent.The Order property overrides scope when determining the order in which filters run. Les filtres sont d’abord classés par ordre, puis l’étendue est utilisée pour couper les liens.Filters are sorted first by order, then scope is used to break ties. Tous les filtres intégrés implémentent IOrderedFilter et affectent 0 à la valeur Order par défaut.All of the built-in filters implement IOrderedFilter and set the default Order value to 0. Pour les filtres intégrés, l’étendue détermine l’ordre, sauf si Order est défini sur une valeur différente de zéro.For built-in filters, scope determines order unless Order is set to a non-zero value.

Annulation et court-circuitCancellation and short-circuiting

Vous pouvez court-circuiter le pipeline de filtres en définissant la propriété Result sur le paramètre ResourceExecutingContext fourni à la méthode de filtre.The filter pipeline can be short-circuited by setting the Result property on the ResourceExecutingContext parameter provided to the filter method. Par exemple, le filtre de ressources suivant empêche l’exécution du reste du 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)
    {
    }
}

Dans le code suivant, les filtres ShortCircuitingResourceFilter et AddHeader ciblent tous deux la méthode d’action SomeResource.In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. Voici le ShortCircuitingResourceFilter :The ShortCircuitingResourceFilter:

  • S’exécute en premier (puisqu’il s’agit d’un filtre de ressources et que AddHeader est un filtre d’action).Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
  • Court-circuite le reste du pipeline.Short-circuits the rest of the pipeline.

Le filtre AddHeader ne s’exécute donc jamais pour l’action SomeResource.Therefore the AddHeader filter never runs for the SomeResource action. Ce comportement est le même si les deux filtres sont appliqués au niveau de la méthode d’action, à condition que ShortCircuitingResourceFilter soit exécuté en premier.This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. ShortCircuitingResourceFilter s’exécute en premier en raison de son type de filtre ou de l’utilisation explicite de la propriété 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.");
    }

Injection de dépendancesDependency injection

Les filtres peuvent être ajoutés par type ou par instance.Filters can be added by type or by instance. Si vous ajoutez une instance, celle-ci sera utilisée pour chaque requête.If an instance is added, that instance is used for every request. Si un type est ajouté, il est activé par type.If a type is added, it's type-activated. Un filtre activé par type signifie :A type-activated filter means:

  • Une instance est créée pour chaque requête.An instance is created for each request.
  • Les dépendances de constructeur sont remplies par l’injection de dépendances (DI).Any constructor dependencies are populated by dependency injection (DI).

Les filtres qui sont implémentés en tant qu’attributs et ajoutés directement à des classes de contrôleur ou à de méthodes d’action ne peut pas avoir de dépendances de constructeur fournies par injection de dépendances.Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). Les dépendances de constructeur ne peuvent pas être fournies par l’injection de dépendance, car :Constructor dependencies cannot be provided by DI because:

  • Les paramètres du constructeur des attributs doivent être fournis là où ils sont appliqués.Attributes must have their constructor parameters supplied where they're applied.
  • Il s’agit d’une limitation de la façon dont les attributs fonctionnent.This is a limitation of how attributes work.

Les filtres suivants prennent en charge les dépendances de constructeur fournies à partir de l’injection de dépendances :The following filters support constructor dependencies provided from DI:

Les filtres précédents peuvent être appliqués à une méthode de contrôleur ou d’action :The preceding filters can be applied to a controller or action method:

Des enregistreurs d’événements sont disponibles à partir de l’injection de dépendances.Loggers are available from DI. Toutefois, évitez la création et l’utilisation de filtres à des fins purement d’enregistrement.However, avoid creating and using filters purely for logging purposes. L’enregistrement d’infrastructure intégrée fournit généralement ce qui est nécessaire pour l’enregistrement.The built-in framework logging typically provides what's needed for logging. Enregistrement ajouté aux filtres :Logging added to filters:

  • Doit se concentrer sur les problèmes ou le comportement du domaine métier spécifique au filtre.Should focus on business domain concerns or behavior specific to the filter.
  • Ne doit pas enregistrer des actions ou d’autres événements d’infrastructure.Should not log actions or other framework events. Les filtres intégrés enregistrent des actions et des événements d’infrastructure.The built in filters log actions and framework events.

ServiceFilterAttributeServiceFilterAttribute

Les types d’implémentation du filtre de services sont enregistrés dans ConfigureServices.Service filter implementation types are registered in ConfigureServices. Un ServiceFilterAttribute récupère une instance du filtre à partir de l’injection de dépendances.A ServiceFilterAttribute retrieves an instance of the filter from DI.

Le code suivant affiche le 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}");
    }

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

Dans le code suivant, AddHeaderResultServiceFilter est ajouté au conteneur d’injection de dépendance :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);
}

Dans le code suivant, l’attribut ServiceFilter récupère une instance du filtre AddHeaderResultServiceFilter à partir de l’injection de dépendances :In the following code, the ServiceFilter attribute retrieves an instance of the AddHeaderResultServiceFilter filter from DI:

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

ServiceFilterAttribute.IsReusable :ServiceFilterAttribute.IsReusable:

  • Conseille que l’instance de filtre peut être réutilisée en dehors de l’étendue de la requête dans laquelle elle a été créée.Provides a hint that the filter instance may be reused outside of the request scope it was created within. Le runtime ASP.NET Core ne garantit pas :The ASP.NET Core runtime doesn't guarantee:

    • Qu’une seule instance du filtre sera créée.That a single instance of the filter will be created.
    • Le filtre ne sera pas demandé à nouveau à partir du conteneur d’injection de dépendance à un stade ultérieur.The filter will not be re-requested from the DI container at some later point.
  • Évitez de l’utiliser avec un filtre qui dépend de services avec une durée de vie autre que singleton.Should not be used with a filter that depends on services with a lifetime other than singleton.

L'objet ServiceFilterAttribute implémente l'objet IFilterFactory.ServiceFilterAttribute implements IFilterFactory. IFilterFactory expose la méthode CreateInstance pour la création d’une instance IFilterMetadata.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance charge le type spécifié à partir de l’injection de dépendances.CreateInstance loads the specified type from DI.

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttribute est similaire à ServiceFilterAttribute, mais son type n’est pas résolu directement à partir du conteneur d’injection de dépendances.TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. Il instancie le type en utilisant Microsoft.Extensions.DependencyInjection.ObjectFactory.It instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

Étant donné que les types TypeFilterAttribute ne sont pas résolus directement à partir du conteneur d’injection de dépendances :Because TypeFilterAttribute types aren't resolved directly from the DI container:

  • Les types qui sont référencés avec TypeFilterAttribute ne doivent pas d’abord être inscrits auprès du conteneur d’injection de dépendances.Types that are referenced using the TypeFilterAttribute don't need to be registered with the DI container. Leurs dépendances ne sont pas remplies par le conteneur d’injection de dépendances.They do have their dependencies fulfilled by the DI container.
  • TypeFilterAttribute peut éventuellement accepter des arguments de constructeur pour le type.TypeFilterAttribute can optionally accept constructor arguments for the type.

Lorsque vous utilisez TypeFilterAttribute, la définition de IsReusable indique que l’instance de filtre peut être réutilisée en dehors de l’étendue de la requête dans laquelle il a été créé.When using TypeFilterAttribute, setting IsReusable is a hint that the filter instance may be reused outside of the request scope it was created within. Le runtime ASP.NET Core ne fournit aucune garantie qu’une seule instance du filtre sera créée.The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created. IsReusable ne doit pas être utilisé avec un filtre qui dépend de services avec une durée de vie autre que singleton.IsReusable should not be used with a filter that depends on services with a lifetime other than singleton.

L’exemple suivant indique comment passer des arguments vers un type en utilisant 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)
    { }
}

Filtres d’autorisationsAuthorization filters

Filtres d’autorisations :Authorization filters:

  • Sont les premiers filtres à être exécutés dans le pipeline de filtres.Are the first filters run in the filter pipeline.
  • Contrôlent l’accès aux méthodes d’action.Control access to action methods.
  • Ont une méthode avant, mais pas de méthode après.Have a before method, but no after method.

Les filtres d’autorisations personnalisés nécessitent une infrastructure d’autorisation personnalisée.Custom authorization filters require a custom authorization framework. Préférez la configuration des stratégies d’autorisation ou l’écriture d’une stratégie d’autorisation personnalisée à l’écriture d’un filtre personnalisé.Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. Le filtre d'autorisations intégré :The built-in authorization filter:

  • Appelle le système d’autorisation.Calls the authorization system.
  • N’autoriser les requêtes.Does not authorize requests.

Ne levez pas d’exceptions dans les filtres d’autorisations :Do not throw exceptions within authorization filters:

  • L’exception ne sera pas gérée.The exception will not be handled.
  • Les filtres d’exceptions ne gèreront pas l’exception.Exception filters will not handle the exception.

Songez à émettre une stimulation quand un filtre d’autorisations se produit.Consider issuing a challenge when an exception occurs in an authorization filter.

Découvrez plus d’informations sur l’autorisation.Learn more about Authorization.

Filtres de ressourcesResource filters

Filtres de ressources :Resource filters:

Les filtres de ressources sont utiles pour court-circuiter la majeure partie du pipeline.Resource filters are useful to short-circuit most of the pipeline. Par exemple, un filtre de mise en cache peut éviter le reste du pipeline dans une correspondance dans le cache.For example, a caching filter can avoid the rest of the pipeline on a cache hit.

Exemples de filtre de ressources :Resource filter examples:

Filtres d’actionsAction filters

Important

Les filtres d’action ne s’appliquent pas aux Razor Pages.Action filters do not apply to Razor Pages. Razor Pages prennent en charge IPageFilter et IAsyncPageFilter .Razor Pages supports IPageFilter and IAsyncPageFilter . Pour plus d’informations, consultez Méthodes de filtre pour les pages Razor.For more information, see Filter methods for Razor Pages.

Filtres d'actions :Action filters:

Le code suivant montre un exemple de filtre d’actions :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.
    }
}

ActionExecutingContext fournit les propriétés suivantes :The ActionExecutingContext provides the following properties:

  • ActionArguments : permet de lire les entrées vers une méthode d’action.ActionArguments - enables the inputs to an action method be read.
  • Controller : permet de manipuler l’instance de contrôleur.Controller - enables manipulating the controller instance.
  • Result : la définition de Result court-circuite l’exécution de la méthode d’action et les filtres d’actions suivants.Result - setting Result short-circuits execution of the action method and subsequent action filters.

Levée d’une exception dans une méthode d’action :Throwing an exception in an action method:

  • Empêche l’exécution des filtres suivants.Prevents running of subsequent filters.
  • Contrairement au paramètre Result, est traité comme un échec plutôt que comme un résultat positif.Unlike setting Result, is treated as a failure instead of a successful result.

ActionExecutedContext fournit Controller et Result, en plus des propriétés suivantes :The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled : sa valeur est true si l’exécution de l’action a été court-circuitée par un autre filtre.Canceled - True if the action execution was short-circuited by another filter.

  • Exception : sa valeur est non Null si l’action ou un filtre d’actions précédemment exécuté a lancé une exception.Exception - Non-null if the action or a previously run action filter threw an exception. Paramètre de cette propriété sur null :Setting this property to null:

    • Gère effectivement une exception.Effectively handles the exception.
    • Result est exécuté comme s’il avait été retourné à partir de la méthode d’action.Result is executed as if it was returned from the action method.

Pour un IAsyncActionFilter, un appel à ActionExecutionDelegate :For an IAsyncActionFilter, a call to the ActionExecutionDelegate:

  • Exécute tous les filtres d’actions suivants et la méthode d’action.Executes any subsequent action filters and the action method.
  • Retourne ActionExecutedContext.Returns ActionExecutedContext.

Pour court-circuiter, attribuez Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result à une instance de résultat et n’appelez pas le next (le ActionExecutionDelegate).To short-circuit, assign Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result to a result instance and don't call next (the ActionExecutionDelegate).

L’infrastructure fournit un ActionFilterAttribute abstrait que vous pouvez placer dans une sous-classe.The framework provides an abstract ActionFilterAttribute that can be subclassed.

Le filtre d’actions OnActionExecuting peut être utilisé pour :The OnActionExecuting action filter can be used to:

  • Valider l’état du modèle.Validate model state.
  • Renvoyer une erreur si l’état n’est pas valide.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);
        }
    }

La méthode OnActionExecuted s’exécute après la méthode d’action :The OnActionExecuted method runs after the action method:

  • Et peut voir et manipuler les résultats de l’action via la propriété Result.And can see and manipulate the results of the action through the Result property.

  • Canceled est défini sur true si l’exécution de l’action a été court-circuitée par un autre filtre.Canceled is set to true if the action execution was short-circuited by another filter.

  • Exception est défini sur une valeur non Null si l’action ou un filtre d’actions suivant a levé une exception.Exception is set to a non-null value if the action or a subsequent action filter threw an exception. Le fait de définir Exception avec la valeur null :Setting Exception to null:

    • Gère effectivement une exception.Effectively handles an exception.
    • ActionExecutedContext.Result est exécuté comme s’il avait été retourné normalement à partir de la méthode d’action.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);
    }
}

Filtres d’exceptionsException filters

Les filtres d’exceptions :Exception filters:

L’échantillon de filtre d’exceptions suivant utilise un affichage personnalisé des erreurs pour afficher des détails sur les exceptions qui se produisent pendant que l’application est en développement :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 CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

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

    public override 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;
    }
}

Les filtres d’exceptions :Exception filters:

  • N’ont pas d’événements avant et après.Don't have before and after events.
  • Implémentent OnException ou OnExceptionAsync.Implement OnException or OnExceptionAsync.
  • Gèrent des exceptions non prises en charge qui se produisent dans Razor Page ou dans la création des contrôleurs, la liaison de données, les filtres d’actions ou les méthodes d’action.Handle unhandled exceptions that occur in Razor Page or controller creation, model binding, action filters, or action methods.
  • N’interceptent pas les exceptions qui se produisent dans l’exécution des filtres de ressources, des filtres de résultats ou des résultats MVC.Do not catch exceptions that occur in resource filters, result filters, or MVC result execution.

Pour gérer une exception, définissez la propriété ExceptionHandled sur true ou écrivez une réponse.To handle an exception, set the ExceptionHandled property to true or write a response. Ceci arrête la propagation de l’exception.This stops propagation of the exception. Un filtre d’exceptions ne peut pas changer une exception en « réussite ».An exception filter can't turn an exception into a "success". Seul un filtre d’actions peut le faire.Only an action filter can do that.

Les filtres d’exceptions :Exception filters:

  • Conviennent pour intercepter des exceptions qui se produisent dans des actions.Are good for trapping exceptions that occur within actions.
  • N’offrent pas la même souplesse que le middleware (intergiciel) de gestion des erreurs.Are not as flexible as error handling middleware.

Privilégiez le middleware pour la gestion des exceptions.Prefer middleware for exception handling. Utilisez les filtres d’exceptions uniquement lorsque la gestion des erreurs diffère selon la méthode d’action appelée.Use exception filters only where error handling differs based on which action method is called. Par exemple, votre application peut avoir des méthodes d’action à la fois pour des points de terminaison d’API et pour des affichages/HTML.For example, an app might have action methods for both API endpoints and for views/HTML. Les points de terminaison d’API peuvent retourner des informations d’erreur au format JSON, tandis que les actions basées sur une vue peuvent retourner une page d’erreur au format HTML.The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

Filtres de résultatsResult filters

Filtres de résultats :Result filters:

IResultFilter et IAsyncResultFilterIResultFilter and IAsyncResultFilter

Le code suivant indique un filtre de résultats qui ajoute un en-tête 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}");
    }

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

Le type de résultat à exécuter dépend de l’action.The kind of result being executed depends on the action. Une action retournant un affichage inclut tous les traitements Razor dans le cadre de la ViewResult à exécuter.An action returning a view would include all razor processing as part of the ViewResult being executed. Une méthode d’API peut effectuer une sérialisation dans le cadre de l’exécution du résultat.An API method might perform some serialization as part of the execution of the result. Découvrez plus d’informations sur les résultats d’actions.Learn more about action results

Les filtres de résultats sont exécutés seulement pour les résultats qui sont des réussites, quand l’action ou les filtres d’actions produisent un résultat d’action.Result filters are only executed for successful results - when the action or action filters produce an action result. Les filtres de résultats ne sont pas exécutés quand les filtres d’exceptions gèrent une exception.Result filters are not executed when exception filters handle an exception.

La méthode Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting peut court-circuiter l’exécution du résultat d’action et les filtres de résultats suivants en définissant Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel sur 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. Écrivez dans l’objet de réponse quand vous court-circuitez pour éviter de générer une réponse vide.Write to the response object when short-circuiting to avoid generating an empty response. La levée d’une exception dans IResultFilter.OnResultExecuting :Throwing an exception in IResultFilter.OnResultExecuting will:

  • Empêche l’exécution du résultat d’action et des filtres suivants.Prevent execution of the action result and subsequent filters.
  • Est traitée comme une erreur et non comme une réussite.Be treated as a failure instead of a successful result.

Lorsque la méthode Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted s’exécute :When the Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted method runs:

  • La réponse a probablement déjà été envoyée au client et ne peut pas être modifiée.The response has likely been sent to the client and cannot be changed.
  • Si une exception a été levée, le corps de la réponse n’est pas envoyé.If an exception was thrown, the response body is not sent.

ResultExecutedContext.Canceled est défini sur true si l’exécution du résultat d’action a été court-circuitée par un autre filtre.ResultExecutedContext.Canceled is set to true if the action result execution was short-circuited by another filter.

ResultExecutedContext.Exception est défini sur une valeur non Null si le résultat d’action ou un filtre de résultats suivant a levé une exception.ResultExecutedContext.Exception is set to a non-null value if the action result or a subsequent result filter threw an exception. Le paramètre de Exception sur Null gère effectivement une exception et évite à l’exception d’être à nouveau levée par ASP.NET Core plus loin dans le pipeline.Setting Exception to null effectively handles an exception and prevents the exception from being rethrown by ASP.NET Core later in the pipeline. Il n’existe aucun moyen fiable pour écrire des données dans une réponse lors de la gestion d’une exception dans un filtre de résultats.There is no reliable way to write data to a response when handling an exception in a result filter. Si les en-têtes ont été vidés pour le client lorsqu’un résultat d’action lance une exception, il n’existe aucun mécanisme fiable pour envoyer un code d’échec.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.

Pour un IAsyncResultFilter, un appel à await next sur le ResultExecutionDelegate exécute tous les filtres de résultats suivants et le résultat de l’action.For an IAsyncResultFilter, a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. Pour court-circuiter, définissez ResultExecutingContext.Cancel sur true et n’appelez pas 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;
        }

    }
}

L’infrastructure fournit un ResultFilterAttribute abstrait que vous pouvez placer dans une sous-classe.The framework provides an abstract ResultFilterAttribute that can be subclassed. La classe AddHeaderAttribute ci-dessus est un exemple d’un attribut de filtre de résultats.The AddHeaderAttribute class shown previously is an example of a result filter attribute.

IAlwaysRunResultFilter et IAsyncAlwaysRunResultFilterIAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter

Les interfaces IAlwaysRunResultFilter et IAsyncAlwaysRunResultFilter déclarent une implémentation IResultFilter qui s’exécute pour tous les résultats d’action.The IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter interfaces declare an IResultFilter implementation that runs for all action results. Le filtre est appliqué à tous les résultats d’action, sauf si :The filter is applied to all action results unless:

Les filtres autres que IExceptionFilter et IAuthorizationFilter ne court-circuitent pas IAlwaysRunResultFilter et IAsyncAlwaysRunResultFilter.Filters other than IExceptionFilter and IAuthorizationFilter don't short-circuit IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter.

Par exemple, le filtre suivant exécute et définit toujours un résultat d’action (ObjectResult) avec un code d’état 422 Entité non traitée en cas d’échec de la négociation de contenu :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

L'objet IFilterFactory implémente l'objet IFilterMetadata.IFilterFactory implements IFilterMetadata. Par conséquent, une instance de IFilterFactory peut être utilisée comme instance de IFilterMetadata n’importe où dans le pipeline de filtres.Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. Quan se prépare à appeler le filtre, il tente de le caster en IFilterFactory.When the runtime prepares to invoke the filter, it attempts to cast it to an IFilterFactory. Si ce cast réussit, la méthode CreateInstance est appelée pour créer l’instance IFilterMetadata qui sera appelée.If that cast succeeds, the CreateInstance method is called to create the IFilterMetadata instance that is invoked. La conception est flexible, car il n’est pas nécessaire de définir explicitement le pipeline de filtres exact quand l’application démarre.This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.

Une autre approche pour la création de filtres est d’implémenter IFilterFactory à l’aide des implémentations d’attribut personnalisé :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;
        }
    }
}

Le code précédent peut être testé en exécutant l’échantillon de téléchargement :The preceding code can be tested by running the download sample:

  • Appeler les outils de développement F12.Invoke the F12 developer tools.
  • Accédez à https://localhost:5001/Sample/HeaderWithFactory.Navigate to https://localhost:5001/Sample/HeaderWithFactory

Les outils de développement F12 affichent les en-têtes de réponse suivants ajoutés par l’exemple de code :The F12 developer tools display the following response headers added by the sample code:

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

Le code précédent crée l’en-tête de réponse interne : My header.The preceding code creates the internal: My header response header.

IFilterFactory implémenté sur un attributIFilterFactory implemented on an attribute

Les filtres qui implémentent IFilterFactory sont utiles pour les filtres qui :Filters that implement IFilterFactory are useful for filters that:

  • Ne nécessitent pas le passage de paramètres.Don't require passing parameters.
  • Disposent de dépendances de constructeur qui doivent être remplies par l’injection de dépendances.Have constructor dependencies that need to be filled by DI.

L'objet TypeFilterAttribute implémente l'objet IFilterFactory.TypeFilterAttribute implements IFilterFactory. IFilterFactory expose la méthode CreateInstance pour la création d’une instance IFilterMetadata.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance charge le type spécifié à partir du conteneur de services (injection de dépendances).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.");
        }
    }
}

Le code suivant illustre trois approches pour appliquer [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");
}

Dans le code précédent, la décoration de la méthode avec [SampleActionFilter] est la meilleure approche pour appliquer SampleActionFilter.In the preceding code, decorating the method with [SampleActionFilter] is the preferred approach to applying the SampleActionFilter.

Utilisation d’un intergiciel dans le pipeline de filtresUsing middleware in the filter pipeline

Les filtres de ressources fonctionnent comme un intergiciel dans la mesure où ils entourent l’exécution de tout ce qui vient plus tard dans le pipeline.Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. Les filtres diffèrent cependant d’un intergiciel dans la mesure où ils font partie du runtime ASP.NET Core, ce qui signifie qu’ils ont accès au contexte et aux constructions 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.

Pour utiliser un intergiciel comme filtre, créez un type avec une méthode Configure qui spécifie l’intergiciel que vous voulez injecter dans le pipeline de filtres.To use middleware as a filter, create a type with a Configure method that specifies the middleware to inject into the filter pipeline. Voici un exemple qui utilise l’intergiciel de localisation pour établir la culture actuelle d’une requête :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);
    }
}

Utilisez le MiddlewareFilterAttribute pour exécuter l’intergiciel :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}");
}

Les filtres d’intergiciels s’exécutent à la même étape du pipeline de filtres en tant que filtres de ressources, avant la liaison de modèle et après le reste du 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.

Actions suivantesNext actions