Filter in ASP.NET CoreFilters in ASP.NET Core

Von Kirk Larkin, Rick Anderson, Tom Dykstra und Steve SmithBy Kirk Larkin, Rick Anderson, Tom Dykstra, and Steve Smith

Filter ermöglichen es in ASP.NET Core, Code vor oder nach bestimmten Phasen der Anforderungsverarbeitungspipeline auszuführen.Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

Integrierte Filter sind für folgende Aufgaben zuständig:Built-in filters handle tasks such as:

  • Autorisierung (der Zugriff auf Ressourcen, für die ein Benutzer nicht autorisiert ist, wird verhindert)Authorization (preventing access to resources a user isn't authorized for).
  • Zwischenspeicherung von Antworten (die Anforderungspipeline wird unterbrochen, damit eine zwischengespeicherte Antwort zurückgegeben wird)Response caching (short-circuiting the request pipeline to return a cached response).

Durch die Erstellung benutzerdefinierter Filter kann mit aktionsübergreifenden Problemen umgegangen werden.Custom filters can be created to handle cross-cutting concerns. Zu solchen übergreifenden Problemen gehören beispielsweise Fehlerbehandlung, Caching, Konfiguration, Autorisierung und Protokollierung.Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Mit Filtern lässt sich die Duplizierung von Code vermeiden.Filters avoid duplicating code. Sie können zum Beispiel die Fehlerbehandlung in einem Ausnahmefilter konsolidieren.For example, an error handling exception filter could consolidate error handling.

Dieses Dokument gilt für Razor Seiten, API-Controller und Controller mit Ansichten.This document applies to Razor Pages, API controllers, and controllers with views. Filter funktionieren nicht direkt mit- Razor Komponenten.Filters don't work directly with Razor components. Ein Filter kann nur indirekt Einfluss auf eine Komponente haben, wenn Folgendes gilt:A filter can only indirectly affect a component when:

  • Die Komponente ist in eine Seite oder Ansicht eingebettet.The component is embedded in a page or view.
  • Die Seite oder der Controller/die Ansicht verwendet den Filter.The page or controller/view uses the filter.

Zeigen Sie ein Beispiel an, oder laden Sie es herunter (Vorgehensweise zum Herunterladen).View or download sample (how to download).

Die Funktionsweise von FilternHow filters work

Filter werden in der ASP.NET Core-Aktionsaufrufpipeline ausgeführt, die manchmal auch als Filterpipeline bezeichnet wird.Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. Die Filterpipeline wird ausgeführt, nachdem ASP.NET Core die auszuführende Aktion ausgewählt hat.The filter pipeline runs after ASP.NET Core selects the action to execute.

Die Anforderung wird von weiterer Middleware, Routingmiddleware, Aktionsauswahl und der Aktionsaufrufpipeline verarbeitet.

FiltertypenFilter types

Jeder Filtertyp wird in einer anderen Phase der Filterpipeline ausgeführt:Each filter type is executed at a different stage in the filter pipeline:

  • Autorisierungsfilter werden zuerst ausgeführt und dienen dazu, festzustellen, ob der Benutzer für die Anforderung berechtigt ist.Authorization filters run first and are used to determine whether the user is authorized for the request. Autorisierungsfilter schließen die Pipeline kurz, wenn die Anforderung nicht autorisiert ist.Authorization filters short-circuit the pipeline if the request is not authorized.

  • Ressourcen Filter:Resource filters:

    • Werden nach der Autorisierung ausgeführt.Run after authorization.
    • OnResourceExecuting führt Code vor dem Rest der Filterpipeline aus.OnResourceExecuting runs code before the rest of the filter pipeline. Beispielsweise führt OnResourceExecuting Code vor der Modellbindung aus.For example, OnResourceExecuting runs code before model binding.
    • OnResourceExecuted führt Code aus, nachdem der Rest der Pipeline abgeschlossen wurde.OnResourceExecuted runs code after the rest of the pipeline has completed.
  • Aktionsfilter:Action filters:

    • Sie führen Code unmittelbar vor und nach dem Aufruf einer Aktionsmethode aus.Run code immediately before and after an action method is called.
    • Sie können die an eine Aktion übergebenen Argumente ändern.Can change the arguments passed into an action.
    • Sie können das von der Aktion zurückgegebene Ergebnis ändern.Can change the result returned from the action.
    • Werden in Seiten nicht unterstützt Razor .Are not supported in Razor Pages.
  • Ausnahmefilter wenden globale Richtlinien auf unbehandelte Ausnahmen an, die auftreten, bevor etwas in den Antworttext geschrieben wurde.Exception filters apply global policies to unhandled exceptions that occur before the response body has been written to.

  • Ergebnisfilter führen Code unmittelbar vor und nach der Ausführung von Aktionsergebnissen aus.Result filters run code immediately before and after the execution of action results. Sie werden nur ausgeführt, wenn die Aktionsmethode erfolgreich ausgeführt wurde.They run only when the action method has executed successfully. Ergebnisfilter sind hilfreich für Logik, die die Ausführung von Ansichten oder Formatierern umfasst.They are useful for logic that must surround view or formatter execution.

Das folgende Diagramm veranschaulicht, wie die Filtertypen mit der Filterpipeline interagieren.The following diagram shows how filter types interact in the filter pipeline.

Die Anforderung wird von Autorisierungsfilter, Ressourcenfilter, Modellbindung, Aktionsfilter, Aktionsausführung sowie Aktionsergebniskonvertierung, Ausnahmefilter, Ergebnisfilter und Ergebnisausführung verarbeitet.

ImplementierungImplementation

Filter unterstützen sowohl synchrone als auch asynchrone Implementierungen über verschiedene Schnittstellendefinitionen.Filters support both synchronous and asynchronous implementations through different interface definitions.

Synchrone Filter führen Code vor und nach der jeweiligen Pipelinephase aus.Synchronous filters run code before and after their pipeline stage. OnActionExecuting beispielsweise wird aufgerufen, bevor die Aktionsmethode aufgerufen wird.For example, OnActionExecuting is called before the action method is called. OnActionExecuted wird nach der Rückgabe der Aktionsmethode aufgerufen.OnActionExecuted is called after the action method returns.

public class MySampleActionFilter : IActionFilter 
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }
}

Im vorangehenden Code ist mydebug eine Utility-Funktion im Beispiel Download.In the preceding code, MyDebug is a utility function in the sample download.

Asynchrone Filter definieren eine On-Stage-ExecutionAsync-Methode.Asynchronous filters define an On-Stage-ExecutionAsync method. Zum Beispiel OnActionExecutionAsync:For example, OnActionExecutionAsync:

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.
    }
}

Im oben stehenden Code weist der SampleAsyncActionFilter einen ActionExecutionDelegate (next) auf, der die Aktionsmethode ausführt.In the preceding code, the SampleAsyncActionFilter has an ActionExecutionDelegate (next) that executes the action method.

Mehrere FilterphasenMultiple filter stages

Schnittstellen für mehrere Filterphasen können in einer einzigen Klasse implementiert werden.Interfaces for multiple filter stages can be implemented in a single class. Beispielsweise implementiert die ActionFilterAttribute-Klasse:For example, the ActionFilterAttribute class implements:

Implementieren Sie entweder die synchrone oder asynchrone Version einer Filterschnittstelle, aber nicht beide.Implement either the synchronous or the async version of a filter interface, not both. Die Runtime prüft zuerst, ob der Filter die asynchrone Schnittstelle implementiert, und wenn dies der Fall ist, ruft die Runtime diese Schnittstelle auf.The runtime checks first to see if the filter implements the async interface, and if so, it calls that. Wenn dies nicht der Fall ist, ruft es die Methode(n) der synchronen Schnittstelle auf.If not, it calls the synchronous interface's method(s). Wenn die asynchrone und die synchrone Schnittstelle in einer einzigen Klasse implementiert sind, wird nur die asynchrone Methode aufgerufen.If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. Bei Verwendung von abstrakten Klassen wie ActionFilterAttribute überschreiben Sie nur die synchronen Methoden oder die asynchrone Methode für jeden Filtertyp.When using abstract classes like ActionFilterAttribute, override only the synchronous methods or the asynchronous method for each filter type.

Integrierte FilterattributeBuilt-in filter attributes

ASP.NET Core enthält integrierte attributbasierte Filter, die als Unterklasse erstellt und angepasst werden können.ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. Zum Beispiel fügt der folgende Ergebnisfilter der Antwort einen Header hinzu: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);
    }
}

Wie im obigen Beispiel gezeigt, können Filter mithilfe von Attributen Argumente akzeptieren.Attributes allow filters to accept arguments, as shown in the preceding example. Wenden Sie das AddHeaderAttribute auf einen Controller oder eine Aktionsmethode an, und geben Sie den Namen und den Wert des HTTP-Headers an:Apply the AddHeaderAttribute to a controller or action method and specify the name and value of the HTTP header:

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

Verwenden Sie ein Tool wie die Browser Entwicklertools , um die Header zu untersuchen.Use a tool such as the browser developer tools to examine the headers. Unter Antwortheader wird author: Rick Anderson angezeigt.Under Response Headers, author: Rick Anderson is displayed.

Mit dem folgenden Code wird ein ActionFilterAttribute-Element implementiert, das diese Aktionen ausführt:The following code implements an ActionFilterAttribute that:

  • Liest den Titel und den Namen aus dem Konfigurationssystem.Reads the title and name from the configuration system. Im Gegensatz zum vorherigen Beispiel erfordert der folgende Code nicht, dass dem Code Filterparameter hinzugefügt werden.Unlike the previous sample, the following code doesn't require filter parameters to be added to the code.
  • Fügt dem Antwortheader den Titel und den Namen hinzu.Adds the title and name to the response header.
public class MyActionFilterAttribute : ActionFilterAttribute
{
    private readonly PositionOptions _settings;

    public MyActionFilterAttribute(IOptions<PositionOptions> options)
    {
        _settings = options.Value;
        Order = 1;
    }

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

Die Konfigurationsoptionen werden vom Konfigurationssystem mithilfe der Optionsmuster bereitgestellt.The configuration options are provided from the configuration system using the options pattern. Beispielsweise aus der Datei appsettings.json:For example, from the appsettings.json file:

{
    "Position": {
        "Title": "Editor",
        "Name": "Joe Smith"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*"
}

In StartUp.ConfigureServices:In the StartUp.ConfigureServices:

  • Die PositionOptions-Klasse wird dem Dienstcontainer mit dem Konfigurationsbereich "Position" hinzugefügt.The PositionOptions class is added to the service container with the "Position" configuration area.
  • MyActionFilterAttribute wird dem Dienstcontainer hinzugefügt.The MyActionFilterAttribute is added to the service container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(
             Configuration.GetSection("Position"));
    services.AddScoped<MyActionFilterAttribute>();

    services.AddControllersWithViews();
}

Der folgende Code zeigt die PositionOptions-Klasse:The following code shows the PositionOptions class:

public class PositionOptions
{
    public string Title { get; set; }
    public string Name { get; set; }
}

Der folgende Code wendet das MyActionFilterAttribute auf die Methode Index2 an:The following code applies the MyActionFilterAttribute to the Index2 method:

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

    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public IActionResult Index2()
    {
        return Content("Header values by configuration.");
    }

Unter den Antwort Headern author: Rick Anderson Editor: Joe Smith wird und angezeigt, wenn der Sample/Index2 Endpunkt aufgerufen wird.Under Response Headers, author: Rick Anderson, and Editor: Joe Smith is displayed when the Sample/Index2 endpoint is called.

Der folgende Code wendet MyActionFilterAttribute und AddHeaderAttribute auf die Seite an Razor :The following code applies the MyActionFilterAttribute and the AddHeaderAttribute to the Razor Page:

[AddHeader("Author", "Rick Anderson")]
[ServiceFilter(typeof(MyActionFilterAttribute))]
public class IndexModel : PageModel
{
    public void OnGet()
    {
    }
}

Filter können nicht auf Razor seitenhandlermethoden angewendet werden.Filters cannot be applied to Razor Page handler methods. Sie können entweder auf das Razor Seiten Modell oder Global angewendet werden.They can be applied either to the Razor Page model or globally.

Einige der Filterschnittstellen besitzen entsprechende Attribute, die als Basisklassen für benutzerdefinierte Implementierungen verwendet werden können.Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

Filterattribute:Filter attributes:

Filterbereiche und Reihenfolge der AusführungFilter scopes and order of execution

Der Pipeline kann in einem von drei Bereichen ein Filter hinzugefügt werden:A filter can be added to the pipeline at one of three scopes:

  • Verwenden eines Attributs für eine Controller-Aktion.Using an attribute on a controller action. Filter Attribute können nicht auf Razor Seiten Handlermethoden angewendet werden.Filter attributes cannot be applied to Razor Pages handler methods.
  • Verwenden eines Attributs auf einem Controller oder einer Razor Seite.Using an attribute on a controller or Razor Page.
  • Global für alle Controller, Aktionen und Razor Seiten, wie im folgenden Code gezeigt:Globally for all controllers, actions, and Razor Pages as shown in the following code:
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter));
    });
}

Standardreihenfolge der AusführungDefault order of execution

Wenn es mehrere Filter für eine bestimmte Stufe der Pipeline gibt, bestimmt der Bereich die Standardreihenfolge der Filterausführung.When there are multiple filters for a particular stage of the pipeline, scope determines the default order of filter execution. Globale Filter umfassen Klassenfilter, welche hingegen Methodenfilter umfassen.Global filters surround class filters, which in turn surround method filters.

Als Ergebnis der Filterschachtelung wird der nach einer Pipelinephase auszuführende Code in umgekehrter Reihenfolge zum Code vor einer Pipelinephase ausgeführt.As a result of filter nesting, the after code of filters runs in the reverse order of the before code. Filterreihenfolge:The filter sequence:

  • Der Code von globalen Filtern, der vor einer Pipelinephase ausgeführt werden sollThe before code of global filters.
    • Der vor -Code von Controller-und Razor Seiten filtern.The before code of controller and Razor Page filters.
      • Der Code von Aktionsmethodenfiltern, der vor einer Pipelinephase ausgeführt werden sollThe before code of action method filters.
      • Der Code von Aktionsmethodenfiltern, der nach einer Pipelinephase ausgeführt werden sollThe after code of action method filters.
    • Der after -Code von Controller-und Razor Seiten filtern.The after code of controller and Razor Page filters.
  • Der Code von globalen Filtern, der nach einer Pipelinephase ausgeführt werden sollThe after code of global filters.

Das folgende Beispiel veranschaulicht die Reihenfolge, in der Filtermethoden für synchrone Aktionsfilter aufgerufen werden.The following example that illustrates the order in which filter methods are called for synchronous action filters.

SequenzSequence FilterbereichFilter scope FiltermethodeFilter method
11 GlobalGlobal OnActionExecuting
22 Controller oder Razor SeiteController or Razor Page OnActionExecuting
33 MethodeMethod OnActionExecuting
44 MethodeMethod OnActionExecuted
55 Controller oder Razor SeiteController or Razor Page OnActionExecuted
66 GlobalGlobal OnActionExecuted

Filter auf ControllerebeneController level filters

Jeder Controller, der von der Basisklasse Controller erbt, enthält die Methoden Controller.OnActionExecuting, Controller.OnActionExecutionAsync und Controller.OnActionExecuted OnActionExecuted.Every controller that inherits from the Controller base class includes Controller.OnActionExecuting, Controller.OnActionExecutionAsync, and Controller.OnActionExecuted OnActionExecuted methods. Diese Methoden führen Folgendes aus:These methods:

  • Die Filter, die für eine bestimmte Aktion ausgeführt werden, werden umschlossen.Wrap the filters that run for a given action.
  • OnActionExecuting wird vor allen Filtern der Aktion aufgerufen.OnActionExecuting is called before any of the action's filters.
  • OnActionExecuted wird nach allen Filtern der Aktion aufgerufen.OnActionExecuted is called after all of the action filters.
  • OnActionExecutionAsync wird vor allen Filtern der Aktion aufgerufen.OnActionExecutionAsync is called before any of the action's filters. Code im Filter nach next wird nach der Aktionsmethode ausgeführt.Code in the filter after next runs after the action method.

Im Downloadbeispiel wird MySampleActionFilter global beim Start angewendet.For example, in the download sample, MySampleActionFilter is applied globally in startup.

Die TestController:The TestController:

  • Wendet das SampleActionFilterAttribute ([SampleActionFilter]) auf die Aktion FilterTest2 an.Applies the SampleActionFilterAttribute ([SampleActionFilter]) to the FilterTest2 action.
  • Überschreibt OnActionExecuting und OnActionExecuted:Overrides OnActionExecuting and OnActionExecuted.
public class TestController : Controller
{
    [SampleActionFilter(Order = int.MinValue)]
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

MyDisplayRouteInfo wird von dem NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt und zeigt Routeninformationen an.MyDisplayRouteInfo is provided by the Rick.Docs.Samples.RouteInfo NuGet package and displays route information.

Durch Navigieren zu https://localhost:5001/Test2/FilterTest2 wird der folgende Code ausgeführt:Navigating to https://localhost:5001/Test2/FilterTest2 runs the following code:

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

Filter auf Controllerebene legen die Eigenschaft Order auf int.MinValue fest.Controller level filters set the Order property to int.MinValue. Für Filter auf Controllerebene kann die Ausführung nach Filtern, die auf Methoden angewendet werden nicht festgelegt werden.Controller level filters can not be set to run after filters applied to methods. Die Reihenfolge wird im nächsten Abschnitt erläutert.Order is explained in the next section.

Informationen zu Razor Seiten finden Sie unter Implementieren von Seiten Razor Filtern durch Überschreiben von Filter Methoden.For Razor Pages, see Implement Razor Page filters by overriding filter methods.

Überschreiben der StandardreihenfolgeOverriding the default order

Die Standardreihenfolge der Ausführung kann durch Implementieren von IOrderedFilter überschrieben werden.The default sequence of execution can be overridden by implementing IOrderedFilter. IOrderedFilter macht die Eigenschaft Order verfügbar, die bei der Bestimmung der Ausführungsreihenfolge Vorrang vor dem Bereich hat.IOrderedFilter exposes the Order property that takes precedence over scope to determine the order of execution. Für einen Filter mit geringerem Order-Wert gilt:A filter with a lower Order value:

  • Führt den Code, der vor einer Pipelinephase ausgeführt werden soll, vor dem Code eines Filters mit einem höheren Wert für Order aus.Runs the before code before that of a filter with a higher value of Order.
  • Führt den Code, der nach einer Pipelinephase ausgeführt werden soll, nach dem Code eines Filters mit einem höheren Wert für Order aus.Runs the after code after that of a filter with a higher Order value.

Die Eigenschaft Order wird mit einem Konstruktorparameter festgelegt:The Order property is set with a constructor parameter:

[SampleActionFilter(Order = int.MinValue)]

Sehen Sie sich die zwei Aktionsfilter im folgenden Controller an:Consider the two action filters in the following controller:

[MyAction2Filter]
public class Test2Controller : Controller
{
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

In StartUp.ConfigureServices wird ein globaler Filter hinzugefügt:A global filter is added in StartUp.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter));
    });
}

Die 3 Filter werden in der folgenden Reihenfolge ausgeführt:The 3 filters run in the following order:

  • Test2Controller.OnActionExecuting
    • MySampleActionFilter.OnActionExecuting
      • MyAction2FilterAttribute.OnActionExecuting
        • Test2Controller.FilterTest2
      • MySampleActionFilter.OnActionExecuted
    • MyAction2FilterAttribute.OnResultExecuting
  • Test2Controller.OnActionExecuted

Die Eigenschaft Order hat bei der Bestimmung der Reihenfolge, in der Filter ausgeführt werden, Vorrang vor dem Bereich.The Order property overrides scope when determining the order in which filters run. Filter werden erst nach der Reihenfolge sortiert, und dann werden Gleichstände über den Bereich aufgelöst.Filters are sorted first by order, then scope is used to break ties. Alle integrierten Filter implementieren IOrderedFilter und legen den Standartwert von Order auf 0 fest.All of the built-in filters implement IOrderedFilter and set the default Order value to 0. Wie zuvor erwähnt, legen Filter auf Controllerebene die Order-Eigenschaft auf int.MinValue fest. Bei integrierten Filtern bestimmt der Umfang die Reihenfolge, es sei denn, Order ist auf einen Wert ungleich null festgelegt.As mentioned previously, controller level filters set the Order property to int.MinValue For built-in filters, scope determines order unless Order is set to a non-zero value.

Im vorstehenden Code hat MySampleActionFilter globalen Umfang und wird daher vor MyAction2FilterAttribute ausgeführt, der Controllerumfang aufweist.In the preceding code, MySampleActionFilter has global scope so it runs before MyAction2FilterAttribute, which has controller scope. Um MyAction2FilterAttribute zuerst ausführen zu lassen, legen Sie die Reihenfolge auf int.MinValue fest:To make MyAction2FilterAttribute run first, set the order to int.MinValue:

[MyAction2Filter(int.MinValue)]
public class Test2Controller : Controller
{
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

Um zuerst den globalen Filter MySampleActionFilter ausführen zu lassen, legen Sie Order auf int.MinValue fest:To make the global filter MySampleActionFilter run first, set Order to int.MinValue:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter),
                            int.MinValue);
    });
}

Abbrechen und KurzschließenCancellation and short-circuiting

Die Filterpipeline kann kurzgeschlossen werden, indem die Eigenschaft Result auf den Parameter ResourceExecutingContext festgelegt wird, der in der Filtermethode angegeben ist.The filter pipeline can be short-circuited by setting the Result property on the ResourceExecutingContext parameter provided to the filter method. Zum Beispiel verhindert der folgende Ressourcenfilter, dass der Rest der Pipeline ausgeführt wird: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)
    {
    }
}

Im folgenden Code verwenden sowohl der Filter ShortCircuitingResourceFilter und der Filter AddHeader die Aktionsmethode SomeResource als Ziel.In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. Die ShortCircuitingResourceFilter:The ShortCircuitingResourceFilter:

  • Der Filter wird zuerst ausgeführt, da es sich um einen Ressourcenfilter handelt und AddHeader ein Aktionsfilter ist.Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
  • Der Filter unterbricht alle verbleibenden Pipelineschritte.Short-circuits the rest of the pipeline.

Der AddHeader-Filter wird daher nie für die SomeResource-Aktion ausgeführt.Therefore the AddHeader filter never runs for the SomeResource action. Dasselbe Verhalten würde auch dann auftreten, wenn beide Filter auf Aktionsmethodenebene angewendet würden, wenn ShortCircuitingResourceFilter zuerst ausgeführt wird.This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. Der ShortCircuitingResourceFilter wird aufgrund seines Filtertyps oder durch die explizite Verwendung der Order-Eigenschaft zuerst ausgeführt.The ShortCircuitingResourceFilter runs first because of its filter type, or by explicit use of Order property.

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

AbhängigkeitsinjektionDependency injection

Filter können nach Typ oder Instanz hinzugefügt werden.Filters can be added by type or by instance. Wenn eine Instanz hinzugefügt wird, wird diese Instanz für jede Anforderung verwendet.If an instance is added, that instance is used for every request. Wenn ein Typ hinzugefügt wird, ist der Filter typaktiviert.If a type is added, it's type-activated. Ein typaktivierter Filter bedeutet Folgendes:A type-activated filter means:

  • Für jede Anforderung wird eine Instanz erstellt.An instance is created for each request.
  • Alle Konstruktorabhängigkeiten werden durch Dependency Injection (DI) aufgefüllt.Any constructor dependencies are populated by dependency injection (DI).

Filter, die als Attribute implementiert und Controllerklassen oder Aktionsmethoden direkt hinzugefügt werden, können keine Konstruktorabhängigkeiten von Dependency Injection (DI) erhalten.Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). Konstruktorabhängigkeiten können aus folgenden Gründen von DI nicht bereitgestellt werden:Constructor dependencies cannot be provided by DI because:

  • Für Attribute müssen Konstruktorparameter bereitgestellt werden, wenn sie angewendet werden.Attributes must have their constructor parameters supplied where they're applied.
  • Dies ist eine Einschränkung der Funktionsweise von Attributen.This is a limitation of how attributes work.

Die folgenden Filter unterstützen von DI bereitgestellte Konstruktorabhängigkeiten:The following filters support constructor dependencies provided from DI:

Die oben genannten Filter können auf einen Controller oder eine Aktionsmethode angewendet werden:The preceding filters can be applied to a controller or action method:

DI bietet Protokollierungen.Loggers are available from DI. Vermeiden Sie es jedoch, Filter nur zum Zweck der Protokollierung zu erstellen und zu verwenden.However, avoid creating and using filters purely for logging purposes. Die integrierte Frameworkprotokollierung bietet in der Regel alle Elemente, die für die Protokollierung erforderlich sind.The built-in framework logging typically provides what's needed for logging. Wenn Protokollierung zu Filtern hinzugefügt wird, gilt Folgendes:Logging added to filters:

  • Die Protokollierung sollte mit Schwerpunkt auf geschäftlichen Aspekten oder verhaltensspezifisch für den Filter erfolgen.Should focus on business domain concerns or behavior specific to the filter.
  • Aktionen oder andere Frameworkereignisse sollten nicht protokolliert werden.Should not log actions or other framework events. Die integrierten Filter protokollieren Aktionen und Frameworkereignisse.The built-in filters log actions and framework events.

ServiceFilterAttributeServiceFilterAttribute

Die Typen der Dienstfilterimplementierung werden in ConfigureServices registriert.Service filter implementation types are registered in ConfigureServices. Ein ServiceFilterAttribute ruft eine Instanz des Filter von DI ab.A ServiceFilterAttribute retrieves an instance of the filter from DI.

Der folgende Code zeigt den 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.
        _logger.LogInformation("AddHeaderResultServiceFilter.OnResultExecuted");
    }
}

Im folgenden Code wird AddHeaderResultServiceFilter zum DI-Container hinzugefügt: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.AddControllersWithViews(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
    });
}

Im folgenden Code ruft das ServiceFilter-Attribut eine Instanz des AddHeaderResultServiceFilter-Filters aus DI ab:In the following code, the ServiceFilter attribute retrieves an instance of the AddHeaderResultServiceFilter filter from DI:

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

Beim Verwenden von ServiceFilterAttribute wird ServiceFilterAttribute.IsReusable festgelegt:When using ServiceFilterAttribute, setting ServiceFilterAttribute.IsReusable:

  • Gibt einen Hinweis darauf, dass die Filterinstanz möglicherweise außerhalb des Anforderungsbereichs, in dem sie erstellt wurde, wiederverwendet wird.Provides a hint that the filter instance may be reused outside of the request scope it was created within. Die ASP.NET Core-Runtime bietet keine Garantie für Folgendes:The ASP.NET Core runtime doesn't guarantee:

    • Eine einzelne Instanz des Filters wird erstellt.That a single instance of the filter will be created.
    • Der Filter wird nicht zu einem späteren Zeitpunkt vom DI-Container erneut angefordert.The filter will not be re-requested from the DI container at some later point.
  • Sollte nicht mit einem Filter verwendet werden, der von Diensten mit einer anderen Lebensdauer als der eines Singletons abhängig ist.Should not be used with a filter that depends on services with a lifetime other than singleton.

ServiceFilterAttribute implementiert IFilterFactory.ServiceFilterAttribute implements IFilterFactory. IFilterFactory macht die CreateInstance-Methode zum Erstellen einer IFilterMetadata-Instanz verfügbar.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance lädt den angegebenen Typ aus DI.CreateInstance loads the specified type from DI.

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttribute ähnelt ServiceFilterAttribute. Der zugehörige Typ wird allerdings nicht direkt vom DI-Container aufgelöst.TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. Stattdessen wird der Typ mithilfe von Microsoft.Extensions.DependencyInjection.ObjectFactory instanziiert.It instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

Da TypeFilterAttribute-Typen nicht direkt vom DI-Container aufgelöst werden, gilt Folgendes:Because TypeFilterAttribute types aren't resolved directly from the DI container:

  • Typen, auf die mithilfe von TypeFilterAttribute verwiesen wird, müssen nicht beim DI-Container registriert werden.Types that are referenced using the TypeFilterAttribute don't need to be registered with the DI container. Ihre Abhängigkeiten werden vom DI-Container erfüllt.They do have their dependencies fulfilled by the DI container.
  • TypeFilterAttribute kann optional Konstruktorargumente für den Typ akzeptieren.TypeFilterAttribute can optionally accept constructor arguments for the type.

Beim Verwenden von TypeFilterAttribute wird TypeFilterAttribute.IsReusable festgelegt:When using TypeFilterAttribute, setting TypeFilterAttribute.IsReusable:

  • Gibt einen Hinweis darauf, dass die Filterinstanz möglicherweise außerhalb des Anforderungsbereichs wiederverwendet wird, in dem sie erstellt wurde.Provides hint that the filter instance may be reused outside of the request scope it was created within. Die ASP.NET Core-Runtime bietet keine Garantie dafür, dass eine einzelne Instanz des Filters erstellt wird.The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created.

  • Sollte nicht mit einem Filter verwendet werden, der von Diensten mit einer anderen Lebensdauer als der eines Singletons abhängig ist.Should not be used with a filter that depends on services with a lifetime other than singleton.

Das folgende Beispiel zeigt, wie Sie Argumente durch Verwendung von TypeFilterAttribute an einen Typ übergeben: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}");
}

AutorisierungsfilterAuthorization filters

Für Autorisierungsfilter gilt Folgendes:Authorization filters:

  • Sie werden als erste Filter in der Filterpipeline ausgeführt.Are the first filters run in the filter pipeline.
  • Sie steuern den Zugriff auf Aktionsmethoden.Control access to action methods.
  • Sie verfügen nur über eine Methode, die vor der Aktion ausgeführt wird, nicht jedoch über eine Methode, die nach der Aktion ausgeführt wird.Have a before method, but no after method.

Benutzerdefinierte Autorisierungsfilter erfordern ein benutzerdefiniertes Autorisierungsframework.Custom authorization filters require a custom authorization framework. Statt einen benutzerdefinierten Filter zu schreiben, sollten Sie die Autorisierungsrichtlinien konfigurieren oder eine benutzerdefinierte Autorisierungsrichtlinie schreiben.Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. Für den integrierten Autorisierungsfilter gilt:The built-in authorization filter:

  • Er ruft das Autorisierungssystem auf.Calls the authorization system.
  • Er autorisiert keine Anforderungen.Does not authorize requests.

Lösen Sie keine Ausnahmen in Autorisierungsfiltern aus:Do not throw exceptions within authorization filters:

  • Die Ausnahme wird nicht behandelt.The exception will not be handled.
  • Ausnahmefilter behandeln die Ausnahme nicht.Exception filters will not handle the exception.

Beim Auftreten einer Ausnahme in einem Autorisierungsfilter sollten Sie eine Abfrage erwägen.Consider issuing a challenge when an exception occurs in an authorization filter.

Weitere Informationen finden Sie unter Autorisierung.Learn more about Authorization.

RessourcenfilterResource filters

Für Ressourcenfilter gilt:Resource filters:

Ressourcenfilter sind hilfreich, um den größten Teil der Pipeline kurzzuschließen.Resource filters are useful to short-circuit most of the pipeline. Ein Cachingfilter kann beispielsweise bei einem Cachetreffer den Rest der Pipeline überspringen.For example, a caching filter can avoid the rest of the pipeline on a cache hit.

Beispiele für Ressourcenfilter:Resource filter examples:

AktionsfilterAction filters

Aktionsfilter gelten nicht für Razor Seiten.Action filters do not apply to Razor Pages. Razor-Seiten unterstützen IPageFilter und IAsyncPageFilter .Razor Pages supports IPageFilter and IAsyncPageFilter . Weitere Informationen finden Sie unter Filtermethoden für Razor Pages.For more information, see Filter methods for Razor Pages.

Für Aktionsfilter gilt:Action filters:

Der folgende Code zeigt einen Beispielaktionsfilter:The following code shows a sample action filter:

public class MySampleActionFilter : IActionFilter 
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }
}

ActionExecutingContext bietet folgende Eigenschaften:The ActionExecutingContext provides the following properties:

  • ActionArguments ermöglicht das Lesen der Eingaben für eine Aktionsmethode.ActionArguments - enables reading the inputs to an action method.
  • Controller ermöglicht das Ändern der Controllerinstanz.Controller - enables manipulating the controller instance.
  • Result: Die Festlegung von Result schließt die Ausführung der Aktionsmethode und der nachfolgenden Aktionsfilter kurz.Result - setting Result short-circuits execution of the action method and subsequent action filters.

Durch Auslösen einer Ausnahme in einer Aktionsmethode geschieht Folgendes:Throwing an exception in an action method:

  • Die Ausführung nachfolgender Filter wird verhindert.Prevents running of subsequent filters.
  • Im Gegensatz zum Festlegen von Result wird die ausgelöste Ausnahme wird nicht als erfolgreiches Ergebnis, sondern als Fehler behandelt.Unlike setting Result, is treated as a failure instead of a successful result.

ActionExecutedContext bietet Controller und Result sowie die folgenden Eigenschaften:The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled ist TRUE, wenn die Aktionsausführung durch einen anderen Filter kurzgeschlossen wurde.Canceled - True if the action execution was short-circuited by another filter.

  • Exception ist ungleich NULL, wenn die Aktion oder ein zuvor ausgeführter Aktionsfilter eine Ausnahme ausgelöst hat.Exception - Non-null if the action or a previously run action filter threw an exception. Durch Festlegen dieser Eigenschaft auf NULL geschieht Folgendes:Setting this property to null:

    • Die Ausnahme wird effektiv behandelt.Effectively handles the exception.
    • Result wird so ausgeführt, als wäre das Ergebnis von der Aktionsmethode zurückgegeben worden.Result is executed as if it was returned from the action method.

Bei einem IAsyncActionFilter hat der Aufruf von ActionExecutionDelegate folgende Auswirkungen:For an IAsyncActionFilter, a call to the ActionExecutionDelegate:

  • Alle nachfolgenden Aktionsfilter und die Aktionsmethode werden ausgeführt.Executes any subsequent action filters and the action method.
  • Gibt ActionExecutedContext zurück.Returns ActionExecutedContext.

Weisen Sie einer Ergebnisinstanz Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result zu, und rufen Sie nicht next (den ActionExecutionDelegate) auf, um die Pipeline kurzzuschließen.To short-circuit, assign Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result to a result instance and don't call next (the ActionExecutionDelegate).

Das Framework stellt ein abstraktes ActionFilterAttribute bereit, das als Unterklasse verwendet werden kann.The framework provides an abstract ActionFilterAttribute that can be subclassed.

Der Aktionsfilter OnActionExecuting kann für Folgendes verwendet werden:The OnActionExecuting action filter can be used to:

  • Überprüfen des Modellzustands.Validate model state.
  • Zurückgeben eines Fehlers, wenn der Zustand ungültig ist.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);
        }
    }

Hinweis

Controller, die mit dem-Attribut kommentiert werden, überprüfen [ApiController] automatisch den Modell Zustand und geben eine 400-Antwort zurück.Controllers annotated with the [ApiController] attribute automatically validate model state and return a 400 response. Weitere Informationen finden Sie unter Automatische HTTP 400-Antworten.For more information, see Automatic HTTP 400 responses.

Die Methode OnActionExecuted wird nach der Aktionsmethode ausgeführt. Es gilt Folgendes:The OnActionExecuted method runs after the action method:

  • Die Methode kann die Ergebnisse der Aktion durch die Eigenschaft Result sehen und ändern.And can see and manipulate the results of the action through the Result property.

  • Canceled wird auf TRUE festgelegt, wenn die Ausführung der Aktion durch einen anderen Filter kurzgeschlossen wurde.Canceled is set to true if the action execution was short-circuited by another filter.

  • Exception wird auf einen Wert ungleich NULL festgelegt, wenn die Aktion oder ein nachfolgender Aktionsfilter eine Ausnahme ausgelöst hat.Exception is set to a non-null value if the action or a subsequent action filter threw an exception. Wenn für Exception NULL festgelegt wird,Setting Exception to null:

    • werden Ausnahmen effektiv behandelt,Effectively handles an exception.
    • und ActionExecutedContext.Result wird so ausgeführt, als würde die Eigenschaft normal von der Aktionsmethode zurückgegeben werden.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);
    }
}

AusnahmefilterException filters

Für Ausnahmefilter gilt Folgendes:Exception filters:

Der folgende Beispielausnahmefilter verwendet eine benutzerdefinierte Fehleransicht, um Details zu Ausnahmen anzuzeigen, die auftreten, wenn die App sich in der Entwicklung befindet: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 IWebHostEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

    public CustomExceptionFilter(
        IWebHostEnvironment 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;
    }
}

Mit dem folgenden Code wird der Ausnahmefilter getestet:The following code tests the exception filter:

[TypeFilter(typeof(CustomExceptionFilter))]
public class FailingController : Controller
{
    [AddHeader("Failing Controller", 
               "Won't appear when exception is handled")]
    public IActionResult Index()
    {
        throw new Exception("Testing custom exception filter.");
    }
}

Für Ausnahmefilter gilt Folgendes:Exception filters:

  • Sie verfügen nicht über vorangehende oder darauffolgende Ereignisse.Don't have before and after events.
  • Sie implementieren OnException oder OnExceptionAsync.Implement OnException or OnExceptionAsync.
  • Behandeln von nicht behandelten Ausnahmen, die bei der Razor Erstellung von Seiten oder Controllern, Modell Bindungen, Aktions filtern oder Aktionsmethoden auftreten.Handle unhandled exceptions that occur in Razor Page or controller creation, model binding, action filters, or action methods.
  • Sie erfassen keine Ausnahmen, die in Ressourcenfiltern, Ergebnisfiltern oder bei der Ausführung von MVC-Ergebnissen auftreten.Do not catch exceptions that occur in resource filters, result filters, or MVC result execution.

Um eine Ausnahme zu behandeln, muss die Eigenschaft ExceptionHandled auf true festgelegt oder eine Antwort geschrieben werden.To handle an exception, set the ExceptionHandled property to true or write a response. Dadurch wird die Weitergabe der Ausnahme beendet.This stops propagation of the exception. Ein Ausnahmefilter kann eine Ausnahme nicht in ein „erfolgreiches Ergebnis“ umwandeln.An exception filter can't turn an exception into a "success". Nur ein Aktionsfilter kann das.Only an action filter can do that.

Für Ausnahmefilter gilt Folgendes:Exception filters:

  • Sie eignen sich für das Abfangen von Ausnahmen, die in Aktionen auftreten.Are good for trapping exceptions that occur within actions.
  • Sie sind im Vergleich zu Middleware für die Fehlerbehandlung weniger flexibel.Are not as flexible as error handling middleware.

Sie sollten bei der Ausnahmebehandlung vorzugsweise Middleware verwenden.Prefer middleware for exception handling. Verwenden Sie Ausnahmefilter nur, wenn sich die Fehlerbehandlung unterscheidet, je nachdem, welche Aktionsmethode aufgerufen wird.Use exception filters only where error handling differs based on which action method is called. Zum Beispiel verfügt eine App möglicherweise über Aktionsmethoden für beide API-Endpunkte und für Ansichten bzw. HTML.For example, an app might have action methods for both API endpoints and for views/HTML. Die API-Endpunkte können Fehlerinformationen als JSON zurückgeben, während ansichtsbasierte Aktionen eine Fehlerseite als HTML zurückgeben können.The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

ErgebnisfilterResult filters

Für Ergebnisfilter gilt:Result filters:

IResultFilter und IAsyncResultFilterIResultFilter and IAsyncResultFilter

Der folgende Code zeigt einen Ergebnisfilter, der einen HTTP-Header hinzufügt: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.
        _logger.LogInformation("AddHeaderResultServiceFilter.OnResultExecuted");
    }
}

Die Art des Ergebnisses, das ausgeführt wird, hängt von der jeweiligen Aktion ab.The kind of result being executed depends on the action. Eine Aktion, die eine Ansicht zurückgibt, beinhaltet die gesamte Razor-Verarbeitung als Teil der Ausführung von ViewResult.An action returning a view includes all razor processing as part of the ViewResult being executed. Eine API-Methode führt möglicherweise eine Art Serialisierung als Teil der Ausführung des Ergebnisses durch.An API method might perform some serialization as part of the execution of the result. Erfahren Sie mehr über Aktions Ergebnisse.Learn more about action results.

Ergebnisfilter werden nur ausgeführt, wenn eine Aktion oder ein Aktionsfilter ein Aktionsergebnis liefert.Result filters are only executed when an action or action filter produces an action result. Ergebnisfilter werden in folgenden Fällen nicht ausgeführt:Result filters are not executed when:

  • Ein Autorisierungs- oder Ressourcenfilter schließt die Pipeline kurz.An authorization filter or resource filter short-circuits the pipeline.
  • Ein Ausnahmefilter behandelt eine Ausnahme durch Erzeugen eines Aktionsergebnisses.An exception filter handles an exception by producing an action result.

Die Methode Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting kann die Ausführung des Aktionsergebnisses und der nachfolgenden Ergebnisfilter durch Festlegen von Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel auf true kurzschließen.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. Schreiben Sie beim Kurzschließen in das Antwortobjekt, um zu verhindern, dass eine leere Antwort generiert wird.Write to the response object when short-circuiting to avoid generating an empty response. Das Auslösen einer Ausnahme in IResultFilter.OnResultExecuting bewirkt Folgendes:Throwing an exception in IResultFilter.OnResultExecuting:

  • Die Ausführung des Aktionsergebnisses und der nachfolgenden Filter wird verhindert.Prevents execution of the action result and subsequent filters.
  • Die ausgelöste Ausnahme wird nicht als erfolgreiches Ergebnis, sondern als Fehler behandelt.Is treated as a failure instead of a successful result.

Wenn die Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted-Methode ausgeführt wird, wurde die Antwort wahrscheinlich bereits an den Client gesendet.When the Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted method runs, the response has probably already been sent to the client. Wenn die Antwort bereits an den Client gesendet wurde, kann sie nicht geändert werden.If the response has already been sent to the client, it cannot be changed.

ResultExecutedContext.Canceled wird auf true festgelegt, wenn die Ausführung des Aktionsergebnisses durch einen anderen Filter kurzgeschlossen wurde.ResultExecutedContext.Canceled is set to true if the action result execution was short-circuited by another filter.

ResultExecutedContext.Exception wird auf einen Wert ungleich NULL festgelegt, wenn das Aktionsergebnis oder ein nachfolgender Ergebnisfilter eine Ausnahme ausgelöst hat.ResultExecutedContext.Exception is set to a non-null value if the action result or a subsequent result filter threw an exception. Das Festlegen von Exception auf NULL behandelt eine Ausnahme und verhindert, dass die Ausnahme zu einem späteren Zeitpunkt in der Pipeline ein weiteres Mal ausgelöst wird.Setting Exception to null effectively handles an exception and prevents the exception from being thrown again later in the pipeline. Beim Behandeln einer Ausnahme in einem Ergebnisfilter gibt es keine zuverlässige Möglichkeit, Daten in eine Antwort zu schreiben.There is no reliable way to write data to a response when handling an exception in a result filter. Wenn ein Aktionsergebnis eine Ausnahme auslöst und die Header bereits an den Client übergeben wurden, gibt es keinen zuverlässigen Mechanismus, einen Fehlercode zu senden.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.

Bei einem IAsyncResultFilter führt ein Aufruf von await next im ResultExecutionDelegate alle nachfolgenden Ergebnisfilter und das Aktionsergebnis aus.For an IAsyncResultFilter, a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. Zum Kurzschließen legen Sie ResultExecutingContext.Cancel auf true fest und rufen den ResultExecutionDelegate nicht auf: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;
        }

    }
}

Das Framework stellt ein abstraktes ResultFilterAttribute bereit, das als Unterklasse verwendet werden kann.The framework provides an abstract ResultFilterAttribute that can be subclassed. Die weiter oben gezeigte Klasse AddHeaderAttribute ist ein Beispiel für ein Ergebnisfilterattribut.The AddHeaderAttribute class shown previously is an example of a result filter attribute.

IAlwaysRunResultFilter und IAsyncAlwaysRunResultFilterIAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter

Die Schnittstellen IAlwaysRunResultFilter und IAsyncAlwaysRunResultFilter deklarieren eine IResultFilter-Implementierung, die für alle Aktionsergebnisse ausgeführt wird.The IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter interfaces declare an IResultFilter implementation that runs for all action results. Dies schließt Aktionsergebnisse ein, die von folgenden Filtern generiert werden:This includes action results produced by:

  • Autorisierungs- und Ressourcenfilter, die einen Kurzschluss bewirkenAuthorization filters and resource filters that short-circuit.
  • AusnahmefilterException filters.

Beispielsweise wird der folgende Filter immer ausgeführt und legt ein Aktionsergebnis (ObjectResult) mit dem Statuscode 422 – Einheit kann nicht bearbeitet werden fest, wenn bei der Inhaltsaushandlung ein Fehler auftritt: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 implementiert IFilterMetadata.IFilterFactory implements IFilterMetadata. Deshalb kann eine IFilterFactory-Instanz an einer beliebigen Stelle in der Filterpipeline als IFilterMetadata-Instanz verwendet werden.Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. Wenn die Runtime den Aufruf des Filters vorbereitet, versucht sie, ihn in eine IFilterFactory umzuwandeln.When the runtime prepares to invoke the filter, it attempts to cast it to an IFilterFactory. Wenn diese Umwandlung gelingt, wird die Methode CreateInstance aufgerufen, um die Instanz IFilterMetadata für den Aufruf zu erstellen.If that cast succeeds, the CreateInstance method is called to create the IFilterMetadata instance that is invoked. Da die exakte Filterpipeline beim Start der Anwendung nicht explizit festgelegt werden muss, wird dadurch ein sehr flexibles Design ermöglicht.This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.

Als weiteres Verfahren zum Erstellen von Filtern kann IFilterFactory mithilfe von benutzerdefinierten Attributimplementierungen implementiert werden: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;
        }
    }
}

Der Filter wird im folgenden Code angewendet:The filter is applied in the following code:

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

    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public IActionResult Index2()
    {
        return Content("Header values by configuration.");
    }

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

    [AddHeaderWithFactory]
    public IActionResult HeaderWithFactory()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }
}

Testen Sie den vorangehenden Code durch Ausführen des Downloadbeispiels:Test the preceding code by running the download sample:

  • Rufen Sie die F12-Entwicklungstools auf.Invoke the F12 developer tools.
  • Navigieren Sie zu https://localhost:5001/Sample/HeaderWithFactory.Navigate to https://localhost:5001/Sample/HeaderWithFactory.

Die F12-Entwicklungstools zeigen folgende Antwortheader an, die vom Beispielcode hinzugefügt wurden:The F12 developer tools display the following response headers added by the sample code:

  • Autor:Rick Andersonauthor: Rick Anderson
  • globaladdheader: Result filter added to MvcOptions.Filtersglobaladdheader: Result filter added to MvcOptions.Filters
  • intern:My headerinternal: My header

Der oben stehende Code erstellt den Antwortheader „internal: My header“.The preceding code creates the internal: My header response header.

In einem Attribut implementierte IFilterFactoryIFilterFactory implemented on an attribute

Filter, die IFilterFactory implementieren, eignen sich in folgenden Fällen:Filters that implement IFilterFactory are useful for filters that:

  • Sie erfordern kein Übergeben von Parametern.Don't require passing parameters.
  • Sie verfügen über Konstruktorabhängigkeiten, die durch DI erfüllt werden müssen.Have constructor dependencies that need to be filled by DI.

TypeFilterAttribute implementiert IFilterFactory.TypeFilterAttribute implements IFilterFactory. IFilterFactory macht die CreateInstance-Methode zum Erstellen einer IFilterMetadata-Instanz verfügbar.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance lädt den angegebenen Typ aus dem Dienstecontainer (DI).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("SampleActionFilterAttribute.OnActionExecuting");
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            _logger.LogInformation("SampleActionFilterAttribute.OnActionExecuted");
        }
    }
}

Der folgende Code zeigt drei Ansätze zum Anwenden von [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 TypeFilterTest");
}

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

Im oben stehenden Code ist das Ergänzen der Methode um [SampleActionFilter] der bevorzugte Ansatz zum Anwenden von SampleActionFilter.In the preceding code, decorating the method with [SampleActionFilter] is the preferred approach to applying the SampleActionFilter.

Verwenden von Middleware in der FilterpipelineUsing middleware in the filter pipeline

Ressourcenfilter funktionieren wie Middleware, sie umschließen alle Ausführungen, die später in der Pipeline enthalten sind.Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. Filter unterscheiden sich jedoch insofern von Middleware, dass sie Teil der Runtime sind, was bedeutet, dass sie Zugriff auf Kontext und Konstrukte haben.But filters differ from middleware in that they're part of the runtime, which means that they have access to context and constructs.

Um Middleware als Filter zu verwenden, erstellen Sie einen Typ mit einer Configure-Methode, die die Middleware festlegt, die in die Filterpipeline eingefügt werden soll.To use middleware as a filter, create a type with a Configure method that specifies the middleware to inject into the filter pipeline. Das folgende Beispiel verwendet die Lokalisierungsmiddleware, um die aktuelle Kultur einer Anforderung einzurichten: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);
    }
}

Verwenden Sie das MiddlewareFilterAttribute zum Ausführen der 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}");
}

Middlewarefilter werden zum selben Zeitpunkt in der Filterpipeline wie Ressourcenfilter, vor der Modellbindung und nach dem Rest der Pipeline ausgeführt.Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.

Nächste SchritteNext actions

Von Kirk Larkin, Rick Anderson, Tom Dykstra und Steve SmithBy Kirk Larkin, Rick Anderson, Tom Dykstra, and Steve Smith

Filter ermöglichen es in ASP.NET Core, Code vor oder nach bestimmten Phasen der Anforderungsverarbeitungspipeline auszuführen.Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

Integrierte Filter sind für folgende Aufgaben zuständig:Built-in filters handle tasks such as:

  • Autorisierung (der Zugriff auf Ressourcen, für die ein Benutzer nicht autorisiert ist, wird verhindert)Authorization (preventing access to resources a user isn't authorized for).
  • Zwischenspeicherung von Antworten (die Anforderungspipeline wird unterbrochen, damit eine zwischengespeicherte Antwort zurückgegeben wird)Response caching (short-circuiting the request pipeline to return a cached response).

Durch die Erstellung benutzerdefinierter Filter kann mit aktionsübergreifenden Problemen umgegangen werden.Custom filters can be created to handle cross-cutting concerns. Zu solchen übergreifenden Problemen gehören beispielsweise Fehlerbehandlung, Caching, Konfiguration, Autorisierung und Protokollierung.Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Mit Filtern lässt sich die Duplizierung von Code vermeiden.Filters avoid duplicating code. Sie können zum Beispiel die Fehlerbehandlung in einem Ausnahmefilter konsolidieren.For example, an error handling exception filter could consolidate error handling.

Dieses Dokument gilt für Razor Seiten, API-Controller und Controller mit Ansichten.This document applies to Razor Pages, API controllers, and controllers with views.

Zeigen Sie ein Beispiel an, oder laden Sie es herunter (Vorgehensweise zum Herunterladen).View or download sample (how to download).

Die Funktionsweise von FilternHow filters work

Filter werden in der ASP.NET Core-Aktionsaufrufpipeline ausgeführt, die manchmal auch als Filterpipeline bezeichnet wird.Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. Die Filterpipeline wird ausgeführt, nachdem ASP.NET Core die auszuführende Aktion ausgewählt hat.The filter pipeline runs after ASP.NET Core selects the action to execute.

Die Anforderung wird von weiterer Middleware, Routingmiddleware, Aktionsauswahl und der ASP.NET Core-Aktionsaufrufpipeline verarbeitet.

FiltertypenFilter types

Jeder Filtertyp wird in einer anderen Phase der Filterpipeline ausgeführt:Each filter type is executed at a different stage in the filter pipeline:

  • Autorisierungsfilter werden zuerst ausgeführt und dienen dazu, festzustellen, ob der Benutzer für die Anforderung berechtigt ist.Authorization filters run first and are used to determine whether the user is authorized for the request. Autorisierungsfilter schließen die Pipeline kurz, wenn die Anforderung nicht autorisiert ist.Authorization filters short-circuit the pipeline if the request is unauthorized.

  • Ressourcen Filter:Resource filters:

    • Werden nach der Autorisierung ausgeführt.Run after authorization.
    • OnResourceExecuting kann Code vor dem Rest der Filterpipeline ausführen.OnResourceExecuting can run code before the rest of the filter pipeline. Beispielsweise kann OnResourceExecuting Code vor der Modellbindung ausführen.For example, OnResourceExecuting can run code before model binding.
    • OnResourceExecuted kann Code nach Abschluss der restlichen Pipeline ausführen.OnResourceExecuted can run code after the rest of the pipeline has completed.
  • Aktionsfilter können, vor und nach dem Aufruf einer individuelle Aktionsmethode, Code ausführen.Action filters can run code immediately before and after an individual action method is called. Sie können zur Bearbeitung der Argumente, die an eine Aktion übermittelt werden, und des Ergebnisses, das von der Aktion zurückgegeben wird, verwendet werden.They can be used to manipulate the arguments passed into an action and the result returned from the action. Aktionsfilter werden in Seiten nicht unterstützt Razor .Action filters are not supported in Razor Pages.

  • Ausnahmefilter werden dazu verwendet, globale Richtlinien auf unbehandelte Ausnahmen anzuwenden, die auftreten, bevor etwas in den Antworttext geschrieben wurde.Exception filters are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body.

  • Ergebnisfilter können, vor und nach dem Ergebnis einer ausgeführten individuellen Aktion, Code ausführen.Result filters can run code immediately before and after the execution of individual action results. Sie werden nur ausgeführt, wenn die Aktionsmethode erfolgreich ausgeführt wurde.They run only when the action method has executed successfully. Ergebnisfilter sind hilfreich für Logik, die die Ausführung von Ansichten oder Formatierern umfasst.They are useful for logic that must surround view or formatter execution.

Das folgende Diagramm veranschaulicht, wie die Filtertypen mit der Filterpipeline interagieren.The following diagram shows how filter types interact in the filter pipeline.

Die Anforderung wird von Autorisierungsfilter, Ressourcenfilter, Modellbindung, Aktionsfilter, Aktionsausführung sowie Aktionsergebniskonvertierung, Ausnahmefilter, Ergebnisfilter und Ergebnisausführung verarbeitet.

ImplementierungImplementation

Filter unterstützen sowohl synchrone als auch asynchrone Implementierungen über verschiedene Schnittstellendefinitionen.Filters support both synchronous and asynchronous implementations through different interface definitions.

Synchrone Filter können Code vor (On-Stage-Executing) und nach (On-Stage-Executed) der jeweiligen Pipelinephase ausführen.Synchronous filters can run code before (On-Stage-Executing) and after (On-Stage-Executed) their pipeline stage. OnActionExecuting beispielsweise wird aufgerufen, bevor die Aktionsmethode aufgerufen wird.For example, OnActionExecuting is called before the action method is called. OnActionExecuted wird nach der Rückgabe der Aktionsmethode aufgerufen.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.
    }
}

Asynchrone Filter definieren eine On-Stage-ExecutionAsync-Methode: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.
    }
}

Im oben stehenden Code weist der SampleAsyncActionFilter einen ActionExecutionDelegate (next) auf, der die Aktionsmethode ausführt.In the preceding code, the SampleAsyncActionFilter has an ActionExecutionDelegate (next) that executes the action method. Jede der On-Stage-ExecutionAsync-Methoden akzeptiert einen FilterType-ExecutionDelegate, der die Pipelinephase des Filters ausführt.Each of the On-Stage-ExecutionAsync methods take a FilterType-ExecutionDelegate that executes the filter's pipeline stage.

Mehrere FilterphasenMultiple filter stages

Schnittstellen für mehrere Filterphasen können in einer einzigen Klasse implementiert werden.Interfaces for multiple filter stages can be implemented in a single class. Beispielsweise implementiert die Klasse ActionFilterAttributeIActionFilter, IResultFilter, und deren asynchrone Gegenstücke.For example, the ActionFilterAttribute class implements IActionFilter, IResultFilter, and their async equivalents.

Implementieren Sie entweder die synchrone oder asynchrone Version einer Filterschnittstelle, aber nicht beide.Implement either the synchronous or the async version of a filter interface, not both. Die Runtime prüft zuerst, ob der Filter die asynchrone Schnittstelle implementiert, und wenn dies der Fall ist, ruft die Runtime diese Schnittstelle auf.The runtime checks first to see if the filter implements the async interface, and if so, it calls that. Wenn dies nicht der Fall ist, ruft es die Methode(n) der synchronen Schnittstelle auf.If not, it calls the synchronous interface's method(s). Wenn die asynchrone und die synchrone Schnittstelle in einer einzigen Klasse implementiert sind, wird nur die asynchrone Methode aufgerufen.If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. Bei Verwendung von abstrakten Klassen wie ActionFilterAttribute überschreiben Sie nur die synchronen Methoden oder die asynchrone Methode für jeden Filtertyp.When using abstract classes like ActionFilterAttribute override only the synchronous methods or the async method for each filter type.

Integrierte FilterattributeBuilt-in filter attributes

ASP.NET Core enthält integrierte attributbasierte Filter, die als Unterklasse erstellt und angepasst werden können.ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. Zum Beispiel fügt der folgende Ergebnisfilter der Antwort einen Header hinzu: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);
    }
}

Wie im obigen Beispiel gezeigt, können Filter mithilfe von Attributen Argumente akzeptieren.Attributes allow filters to accept arguments, as shown in the preceding example. Wenden Sie das AddHeaderAttribute auf einen Controller oder eine Aktionsmethode an, und geben Sie den Namen und den Wert des HTTP-Headers an: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.");
    }

Einige der Filterschnittstellen besitzen entsprechende Attribute, die als Basisklassen für benutzerdefinierte Implementierungen verwendet werden können.Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

Filterattribute:Filter attributes:

Filterbereiche und Reihenfolge der AusführungFilter scopes and order of execution

Der Pipeline kann in einem von drei Bereichen ein Filter hinzugefügt werden:A filter can be added to the pipeline at one of three scopes:

  • Verwenden eines Attributs in einer AktionUsing an attribute on an action.
  • Verwenden eines Attributs in einem ControllerUsing an attribute on a controller.
  • Global für alle Controller und Aktionen, wie in folgendem Code gezeigt: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);
}

Der oben stehende Code fügt mithilfe der Sammlung MvcOptions.Filters global drei Filter hinzu.The preceding code adds three filters globally using the MvcOptions.Filters collection.

Standardreihenfolge der AusführungDefault order of execution

Wenn mehrere Filter des gleichen Typs vorhanden sind, bestimmt der Umfang die Standardreihenfolge ihrer Ausführung.When there are multiple filters of the same type, scope determines the default order of filter execution. Globale Filter umschließen Klassenfilter.Global filters surround class filters. Klassenfilter umschließen Methodenfilter.Class filters surround method filters.

Als Ergebnis der Filterschachtelung wird der nach einer Pipelinephase auszuführende Code in umgekehrter Reihenfolge zum Code vor einer Pipelinephase ausgeführt.As a result of filter nesting, the after code of filters runs in the reverse order of the before code. Filterreihenfolge:The filter sequence:

  • Der Code von globalen Filtern, der vor einer Pipelinephase ausgeführt werden sollThe before code of global filters.
    • Der Code von Controllerfiltern, der vor einer Pipelinephase ausgeführt werden sollThe before code of controller filters.
      • Der Code von Aktionsmethodenfiltern, der vor einer Pipelinephase ausgeführt werden sollThe before code of action method filters.
      • Der Code von Aktionsmethodenfiltern, der nach einer Pipelinephase ausgeführt werden sollThe after code of action method filters.
    • Der Code von Controllerfiltern, der nach einer Pipelinephase ausgeführt werden sollThe after code of controller filters.
  • Der Code von globalen Filtern, der nach einer Pipelinephase ausgeführt werden sollThe after code of global filters.

Das folgende Beispiel veranschaulicht die Reihenfolge, in der Filtermethoden für synchrone Aktionsfilter aufgerufen werden.The following example that illustrates the order in which filter methods are called for synchronous action filters.

SequenzSequence FilterbereichFilter scope FiltermethodeFilter method
11 GlobalGlobal OnActionExecuting
22 ControllerController OnActionExecuting
33 MethodeMethod OnActionExecuting
44 MethodeMethod OnActionExecuted
55 ControllerController OnActionExecuted
66 GlobalGlobal OnActionExecuted

Diese Sequenz veranschaulicht Folgendes:This sequence shows:

  • Der Methodenfilter ist innerhalb des Controllerfilters geschachtelt.The method filter is nested within the controller filter.
  • Der Controllerfilter ist innerhalb des globalen Filters geschachtelt.The controller filter is nested within the global filter.

Filter auf Controller-und Razor SeitenebeneController and Razor Page level filters

Jeder Controller, der von der Basisklasse Controller erbt, enthält die Methoden Controller.OnActionExecuting, Controller.OnActionExecutionAsync und Controller.OnActionExecuted OnActionExecuted.Every controller that inherits from the Controller base class includes Controller.OnActionExecuting, Controller.OnActionExecutionAsync, and Controller.OnActionExecuted OnActionExecuted methods. Diese Methoden führen Folgendes aus:These methods:

  • Die Filter, die für eine bestimmte Aktion ausgeführt werden, werden umschlossen.Wrap the filters that run for a given action.
  • OnActionExecuting wird vor allen Filtern der Aktion aufgerufen.OnActionExecuting is called before any of the action's filters.
  • OnActionExecuted wird nach allen Filtern der Aktion aufgerufen.OnActionExecuted is called after all of the action filters.
  • OnActionExecutionAsync wird vor allen Filtern der Aktion aufgerufen.OnActionExecutionAsync is called before any of the action's filters. Code im Filter nach next wird nach der Aktionsmethode ausgeführt.Code in the filter after next runs after the action method.

Im Downloadbeispiel wird MySampleActionFilter global beim Start angewendet.For example, in the download sample, MySampleActionFilter is applied globally in startup.

Die TestController:The TestController:

  • Wendet das SampleActionFilterAttribute ([SampleActionFilter]) auf die Aktion FilterTest2 an.Applies the SampleActionFilterAttribute ([SampleActionFilter]) to the FilterTest2 action.
  • Überschreibt OnActionExecuting und 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);
    }
}

Durch Navigieren zu https://localhost:5001/Test/FilterTest2 wird der folgende Code ausgeführt: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

Informationen zu Razor Seiten finden Sie unter Implementieren von Seiten Razor Filtern durch Überschreiben von Filter Methoden.For Razor Pages, see Implement Razor Page filters by overriding filter methods.

Überschreiben der StandardreihenfolgeOverriding the default order

Die Standardreihenfolge der Ausführung kann durch Implementieren von IOrderedFilter überschrieben werden.The default sequence of execution can be overridden by implementing IOrderedFilter. IOrderedFilter macht die Eigenschaft Order verfügbar, die bei der Bestimmung der Ausführungsreihenfolge Vorrang vor dem Bereich hat.IOrderedFilter exposes the Order property that takes precedence over scope to determine the order of execution. Für einen Filter mit geringerem Order-Wert gilt:A filter with a lower Order value:

  • Führt den Code, der vor einer Pipelinephase ausgeführt werden soll, vor dem Code eines Filters mit einem höheren Wert für Order aus.Runs the before code before that of a filter with a higher value of Order.
  • Führt den Code, der nach einer Pipelinephase ausgeführt werden soll, nach dem Code eines Filters mit einem höheren Wert für Order aus.Runs the after code after that of a filter with a higher Order value.

Die Eigenschaft Order kann mit einem Konstruktorparameter festgelegt werden:The Order property can be set with a constructor parameter:

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

Sehen Sie sich die drei Aktionsfilter an, die im vorherigen Beispiel gezeigt werden.Consider the same 3 action filters shown in the preceding example. Wenn die Order-Eigenschaft des Controllers und der globalen Filter auf 1 bzw. 2 festgelegt ist, wird die Reihenfolge der Ausführung umgekehrt.If the Order property of the controller and global filters is set to 1 and 2 respectively, the order of execution is reversed.

SequenzSequence FilterbereichFilter scope Order-EigenschaftOrder property FiltermethodeFilter method
11 MethodeMethod 00 OnActionExecuting
22 ControllerController 11 OnActionExecuting
33 GlobalGlobal 22 OnActionExecuting
44 GlobalGlobal 22 OnActionExecuted
55 ControllerController 11 OnActionExecuted
66 MethodeMethod 00 OnActionExecuted

Die Eigenschaft Order hat bei der Bestimmung der Reihenfolge, in der Filter ausgeführt werden, Vorrang vor dem Bereich.The Order property overrides scope when determining the order in which filters run. Filter werden erst nach der Reihenfolge sortiert, und dann werden Gleichstände über den Bereich aufgelöst.Filters are sorted first by order, then scope is used to break ties. Alle integrierten Filter implementieren IOrderedFilter und legen den Standartwert von Order auf 0 fest.All of the built-in filters implement IOrderedFilter and set the default Order value to 0. Bei integrierten Filtern bestimmt der Bereich die Reihenfolge, falls Order nicht auf einen Wert ungleich 0 festgelegt ist.For built-in filters, scope determines order unless Order is set to a non-zero value.

Abbrechen und KurzschließenCancellation and short-circuiting

Die Filterpipeline kann kurzgeschlossen werden, indem die Eigenschaft Result auf den Parameter ResourceExecutingContext festgelegt wird, der in der Filtermethode angegeben ist.The filter pipeline can be short-circuited by setting the Result property on the ResourceExecutingContext parameter provided to the filter method. Zum Beispiel verhindert der folgende Ressourcenfilter, dass der Rest der Pipeline ausgeführt wird: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)
    {
    }
}

Im folgenden Code verwenden sowohl der Filter ShortCircuitingResourceFilter und der Filter AddHeader die Aktionsmethode SomeResource als Ziel.In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. Die ShortCircuitingResourceFilter:The ShortCircuitingResourceFilter:

  • Der Filter wird zuerst ausgeführt, da es sich um einen Ressourcenfilter handelt und AddHeader ein Aktionsfilter ist.Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
  • Der Filter unterbricht alle verbleibenden Pipelineschritte.Short-circuits the rest of the pipeline.

Der AddHeader-Filter wird daher nie für die SomeResource-Aktion ausgeführt.Therefore the AddHeader filter never runs for the SomeResource action. Dasselbe Verhalten würde auch dann auftreten, wenn beide Filter auf Aktionsmethodenebene angewendet würden, wenn ShortCircuitingResourceFilter zuerst ausgeführt wird.This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. Der ShortCircuitingResourceFilter wird aufgrund seines Filtertyps oder durch die explizite Verwendung der Order-Eigenschaft zuerst ausgeführt.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.");
    }

AbhängigkeitsinjektionDependency injection

Filter können nach Typ oder Instanz hinzugefügt werden.Filters can be added by type or by instance. Wenn eine Instanz hinzugefügt wird, wird diese Instanz für jede Anforderung verwendet.If an instance is added, that instance is used for every request. Wenn ein Typ hinzugefügt wird, ist der Filter typaktiviert.If a type is added, it's type-activated. Ein typaktivierter Filter bedeutet Folgendes:A type-activated filter means:

  • Für jede Anforderung wird eine Instanz erstellt.An instance is created for each request.
  • Alle Konstruktorabhängigkeiten werden durch Dependency Injection (DI) aufgefüllt.Any constructor dependencies are populated by dependency injection (DI).

Filter, die als Attribute implementiert und Controllerklassen oder Aktionsmethoden direkt hinzugefügt werden, können keine Konstruktorabhängigkeiten von Dependency Injection (DI) erhalten.Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). Konstruktorabhängigkeiten können aus folgenden Gründen von DI nicht bereitgestellt werden:Constructor dependencies cannot be provided by DI because:

  • Für Attribute müssen Konstruktorparameter bereitgestellt werden, wenn sie angewendet werden.Attributes must have their constructor parameters supplied where they're applied.
  • Dies ist eine Einschränkung der Funktionsweise von Attributen.This is a limitation of how attributes work.

Die folgenden Filter unterstützen von DI bereitgestellte Konstruktorabhängigkeiten:The following filters support constructor dependencies provided from DI:

Die oben genannten Filter können auf einen Controller oder eine Aktionsmethode angewendet werden:The preceding filters can be applied to a controller or action method:

DI bietet Protokollierungen.Loggers are available from DI. Vermeiden Sie es jedoch, Filter nur zum Zweck der Protokollierung zu erstellen und zu verwenden.However, avoid creating and using filters purely for logging purposes. Die integrierte Frameworkprotokollierung bietet in der Regel alle Elemente, die für die Protokollierung erforderlich sind.The built-in framework logging typically provides what's needed for logging. Wenn Protokollierung zu Filtern hinzugefügt wird, gilt Folgendes:Logging added to filters:

  • Die Protokollierung sollte mit Schwerpunkt auf geschäftlichen Aspekten oder verhaltensspezifisch für den Filter erfolgen.Should focus on business domain concerns or behavior specific to the filter.
  • Aktionen oder andere Frameworkereignisse sollten nicht protokolliert werden.Should not log actions or other framework events. Die integrierten Filter protokollieren Aktionen und Frameworkereignisse.The built in filters log actions and framework events.

ServiceFilterAttributeServiceFilterAttribute

Die Typen der Dienstfilterimplementierung werden in ConfigureServices registriert.Service filter implementation types are registered in ConfigureServices. Ein ServiceFilterAttribute ruft eine Instanz des Filter von DI ab.A ServiceFilterAttribute retrieves an instance of the filter from DI.

Der folgende Code zeigt den 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.
    }
}

Im folgenden Code wird AddHeaderResultServiceFilter zum DI-Container hinzugefügt: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);
}

Im folgenden Code ruft das ServiceFilter-Attribut eine Instanz des AddHeaderResultServiceFilter-Filters aus DI ab:In the following code, the ServiceFilter attribute retrieves an instance of the AddHeaderResultServiceFilter filter from DI:

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

Beim Verwenden von ServiceFilterAttribute wird ServiceFilterAttribute.IsReusable festgelegt:When using ServiceFilterAttribute, setting ServiceFilterAttribute.IsReusable:

  • Gibt einen Hinweis darauf, dass die Filterinstanz möglicherweise außerhalb des Anforderungsbereichs, in dem sie erstellt wurde, wiederverwendet wird.Provides a hint that the filter instance may be reused outside of the request scope it was created within. Die ASP.NET Core-Runtime bietet keine Garantie für Folgendes:The ASP.NET Core runtime doesn't guarantee:

    • Eine einzelne Instanz des Filters wird erstellt.That a single instance of the filter will be created.
    • Der Filter wird nicht zu einem späteren Zeitpunkt vom DI-Container erneut angefordert.The filter will not be re-requested from the DI container at some later point.
  • Sollte nicht mit einem Filter verwendet werden, der von Diensten mit einer anderen Lebensdauer als der eines Singletons abhängig ist.Should not be used with a filter that depends on services with a lifetime other than singleton.

ServiceFilterAttribute implementiert IFilterFactory.ServiceFilterAttribute implements IFilterFactory. IFilterFactory macht die CreateInstance-Methode zum Erstellen einer IFilterMetadata-Instanz verfügbar.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance lädt den angegebenen Typ aus DI.CreateInstance loads the specified type from DI.

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttribute ähnelt ServiceFilterAttribute. Der zugehörige Typ wird allerdings nicht direkt vom DI-Container aufgelöst.TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. Stattdessen wird der Typ mithilfe von Microsoft.Extensions.DependencyInjection.ObjectFactory instanziiert.It instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

Da TypeFilterAttribute-Typen nicht direkt vom DI-Container aufgelöst werden, gilt Folgendes:Because TypeFilterAttribute types aren't resolved directly from the DI container:

  • Typen, auf die mithilfe von TypeFilterAttribute verwiesen wird, müssen nicht beim DI-Container registriert werden.Types that are referenced using the TypeFilterAttribute don't need to be registered with the DI container. Ihre Abhängigkeiten werden vom DI-Container erfüllt.They do have their dependencies fulfilled by the DI container.
  • TypeFilterAttribute kann optional Konstruktorargumente für den Typ akzeptieren.TypeFilterAttribute can optionally accept constructor arguments for the type.

Beim Verwenden von TypeFilterAttribute wird TypeFilterAttribute.IsReusable festgelegt:When using TypeFilterAttribute, setting TypeFilterAttribute.IsReusable:

  • Gibt einen Hinweis darauf, dass die Filterinstanz möglicherweise außerhalb des Anforderungsbereichs wiederverwendet wird, in dem sie erstellt wurde.Provides hint that the filter instance may be reused outside of the request scope it was created within. Die ASP.NET Core-Runtime bietet keine Garantie dafür, dass eine einzelne Instanz des Filters erstellt wird.The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created.

  • Sollte nicht mit einem Filter verwendet werden, der von Diensten mit einer anderen Lebensdauer als der eines Singletons abhängig ist.Should not be used with a filter that depends on services with a lifetime other than singleton.

Das folgende Beispiel zeigt, wie Sie Argumente durch Verwendung von TypeFilterAttribute an einen Typ übergeben: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)
    { }
}

AutorisierungsfilterAuthorization filters

Für Autorisierungsfilter gilt Folgendes:Authorization filters:

  • Sie werden als erste Filter in der Filterpipeline ausgeführt.Are the first filters run in the filter pipeline.
  • Sie steuern den Zugriff auf Aktionsmethoden.Control access to action methods.
  • Sie verfügen nur über eine Methode, die vor der Aktion ausgeführt wird, nicht jedoch über eine Methode, die nach der Aktion ausgeführt wird.Have a before method, but no after method.

Benutzerdefinierte Autorisierungsfilter erfordern ein benutzerdefiniertes Autorisierungsframework.Custom authorization filters require a custom authorization framework. Statt einen benutzerdefinierten Filter zu schreiben, sollten Sie die Autorisierungsrichtlinien konfigurieren oder eine benutzerdefinierte Autorisierungsrichtlinie schreiben.Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. Für den integrierten Autorisierungsfilter gilt:The built-in authorization filter:

  • Er ruft das Autorisierungssystem auf.Calls the authorization system.
  • Er autorisiert keine Anforderungen.Does not authorize requests.

Lösen Sie keine Ausnahmen in Autorisierungsfiltern aus:Do not throw exceptions within authorization filters:

  • Die Ausnahme wird nicht behandelt.The exception will not be handled.
  • Ausnahmefilter behandeln die Ausnahme nicht.Exception filters will not handle the exception.

Beim Auftreten einer Ausnahme in einem Autorisierungsfilter sollten Sie eine Abfrage erwägen.Consider issuing a challenge when an exception occurs in an authorization filter.

Weitere Informationen finden Sie unter Autorisierung.Learn more about Authorization.

RessourcenfilterResource filters

Für Ressourcenfilter gilt:Resource filters:

Ressourcenfilter sind hilfreich, um den größten Teil der Pipeline kurzzuschließen.Resource filters are useful to short-circuit most of the pipeline. Ein Cachingfilter kann beispielsweise bei einem Cachetreffer den Rest der Pipeline überspringen.For example, a caching filter can avoid the rest of the pipeline on a cache hit.

Beispiele für Ressourcenfilter:Resource filter examples:

AktionsfilterAction filters

Wichtig

Aktionsfilter gelten nicht für Razor Seiten.Action filters do not apply to Razor Pages. Razor-Seiten unterstützen IPageFilter und IAsyncPageFilter .Razor Pages supports IPageFilter and IAsyncPageFilter . Weitere Informationen finden Sie unter Filtermethoden für Razor Pages.For more information, see Filter methods for Razor Pages.

Für Aktionsfilter gilt:Action filters:

Der folgende Code zeigt einen Beispielaktionsfilter: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 bietet folgende Eigenschaften:The ActionExecutingContext provides the following properties:

  • ActionArguments ermöglicht das Lesen der Eingaben für eine Aktionsmethode.ActionArguments - enables the inputs to an action method be read.
  • Controller ermöglicht das Ändern der Controllerinstanz.Controller - enables manipulating the controller instance.
  • Result: Die Festlegung von Result schließt die Ausführung der Aktionsmethode und der nachfolgenden Aktionsfilter kurz.Result - setting Result short-circuits execution of the action method and subsequent action filters.

Durch Auslösen einer Ausnahme in einer Aktionsmethode geschieht Folgendes:Throwing an exception in an action method:

  • Die Ausführung nachfolgender Filter wird verhindert.Prevents running of subsequent filters.
  • Im Gegensatz zum Festlegen von Result wird die ausgelöste Ausnahme wird nicht als erfolgreiches Ergebnis, sondern als Fehler behandelt.Unlike setting Result, is treated as a failure instead of a successful result.

ActionExecutedContext bietet Controller und Result sowie die folgenden Eigenschaften:The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled ist TRUE, wenn die Aktionsausführung durch einen anderen Filter kurzgeschlossen wurde.Canceled - True if the action execution was short-circuited by another filter.

  • Exception ist ungleich NULL, wenn die Aktion oder ein zuvor ausgeführter Aktionsfilter eine Ausnahme ausgelöst hat.Exception - Non-null if the action or a previously run action filter threw an exception. Durch Festlegen dieser Eigenschaft auf NULL geschieht Folgendes:Setting this property to null:

    • Die Ausnahme wird effektiv behandelt.Effectively handles the exception.
    • Result wird so ausgeführt, als wäre das Ergebnis von der Aktionsmethode zurückgegeben worden.Result is executed as if it was returned from the action method.

Bei einem IAsyncActionFilter hat der Aufruf von ActionExecutionDelegate folgende Auswirkungen:For an IAsyncActionFilter, a call to the ActionExecutionDelegate:

  • Alle nachfolgenden Aktionsfilter und die Aktionsmethode werden ausgeführt.Executes any subsequent action filters and the action method.
  • Gibt ActionExecutedContext zurück.Returns ActionExecutedContext.

Weisen Sie einer Ergebnisinstanz Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result zu, und rufen Sie nicht next (den ActionExecutionDelegate) auf, um die Pipeline kurzzuschließen.To short-circuit, assign Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result to a result instance and don't call next (the ActionExecutionDelegate).

Das Framework stellt ein abstraktes ActionFilterAttribute bereit, das als Unterklasse verwendet werden kann.The framework provides an abstract ActionFilterAttribute that can be subclassed.

Der Aktionsfilter OnActionExecuting kann für Folgendes verwendet werden:The OnActionExecuting action filter can be used to:

  • Überprüfen des Modellzustands.Validate model state.
  • Zurückgeben eines Fehlers, wenn der Zustand ungültig ist.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);
        }
    }

Die Methode OnActionExecuted wird nach der Aktionsmethode ausgeführt. Es gilt Folgendes:The OnActionExecuted method runs after the action method:

  • Die Methode kann die Ergebnisse der Aktion durch die Eigenschaft Result sehen und ändern.And can see and manipulate the results of the action through the Result property.

  • Canceled wird auf TRUE festgelegt, wenn die Ausführung der Aktion durch einen anderen Filter kurzgeschlossen wurde.Canceled is set to true if the action execution was short-circuited by another filter.

  • Exception wird auf einen Wert ungleich NULL festgelegt, wenn die Aktion oder ein nachfolgender Aktionsfilter eine Ausnahme ausgelöst hat.Exception is set to a non-null value if the action or a subsequent action filter threw an exception. Wenn für Exception NULL festgelegt wird,Setting Exception to null:

    • werden Ausnahmen effektiv behandelt,Effectively handles an exception.
    • und ActionExecutedContext.Result wird so ausgeführt, als würde die Eigenschaft normal von der Aktionsmethode zurückgegeben werden.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);
    }
}

AusnahmefilterException filters

Für Ausnahmefilter gilt Folgendes:Exception filters:

Der folgende Beispielausnahmefilter verwendet eine benutzerdefinierte Fehleransicht, um Details zu Ausnahmen anzuzeigen, die auftreten, wenn die App sich in der Entwicklung befindet: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;
    }
}

Für Ausnahmefilter gilt Folgendes:Exception filters:

  • Sie verfügen nicht über vorangehende oder darauffolgende Ereignisse.Don't have before and after events.
  • Sie implementieren OnException oder OnExceptionAsync.Implement OnException or OnExceptionAsync.
  • Behandeln von nicht behandelten Ausnahmen, die bei der Razor Erstellung von Seiten oder Controllern, Modell Bindungen, Aktions filtern oder Aktionsmethoden auftreten.Handle unhandled exceptions that occur in Razor Page or controller creation, model binding, action filters, or action methods.
  • Sie erfassen keine Ausnahmen, die in Ressourcenfiltern, Ergebnisfiltern oder bei der Ausführung von MVC-Ergebnissen auftreten.Do not catch exceptions that occur in resource filters, result filters, or MVC result execution.

Um eine Ausnahme zu behandeln, muss die Eigenschaft ExceptionHandled auf true festgelegt oder eine Antwort geschrieben werden.To handle an exception, set the ExceptionHandled property to true or write a response. Dadurch wird die Weitergabe der Ausnahme beendet.This stops propagation of the exception. Ein Ausnahmefilter kann eine Ausnahme nicht in ein „erfolgreiches Ergebnis“ umwandeln.An exception filter can't turn an exception into a "success". Nur ein Aktionsfilter kann das.Only an action filter can do that.

Für Ausnahmefilter gilt Folgendes:Exception filters:

  • Sie eignen sich für das Abfangen von Ausnahmen, die in Aktionen auftreten.Are good for trapping exceptions that occur within actions.
  • Sie sind im Vergleich zu Middleware für die Fehlerbehandlung weniger flexibel.Are not as flexible as error handling middleware.

Sie sollten bei der Ausnahmebehandlung vorzugsweise Middleware verwenden.Prefer middleware for exception handling. Verwenden Sie Ausnahmefilter nur, wenn sich die Fehlerbehandlung unterscheidet, je nachdem, welche Aktionsmethode aufgerufen wird.Use exception filters only where error handling differs based on which action method is called. Zum Beispiel verfügt eine App möglicherweise über Aktionsmethoden für beide API-Endpunkte und für Ansichten bzw. HTML.For example, an app might have action methods for both API endpoints and for views/HTML. Die API-Endpunkte können Fehlerinformationen als JSON zurückgeben, während ansichtsbasierte Aktionen eine Fehlerseite als HTML zurückgeben können.The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

ErgebnisfilterResult filters

Für Ergebnisfilter gilt:Result filters:

IResultFilter und IAsyncResultFilterIResultFilter and IAsyncResultFilter

Der folgende Code zeigt einen Ergebnisfilter, der einen HTTP-Header hinzufügt: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.
    }
}

Die Art des Ergebnisses, das ausgeführt wird, hängt von der jeweiligen Aktion ab.The kind of result being executed depends on the action. Eine Aktion, die eine Ansicht zurückgibt, würde die gesamte Razor-Verarbeitung als Teil der Ausführung von ViewResult beinhalten.An action returning a view would include all razor processing as part of the ViewResult being executed. Eine API-Methode führt möglicherweise eine Art Serialisierung als Teil der Ausführung des Ergebnisses durch.An API method might perform some serialization as part of the execution of the result. Erfahren Sie mehr über Aktions Ergebnisse.Learn more about action results.

Ergebnisfilter werden nur ausgeführt, wenn eine Aktion oder ein Aktionsfilter ein Aktionsergebnis liefert.Result filters are only executed when an action or action filter produces an action result. Ergebnisfilter werden in folgenden Fällen nicht ausgeführt:Result filters are not executed when:

  • Ein Autorisierungs- oder Ressourcenfilter schließt die Pipeline kurz.An authorization filter or resource filter short-circuits the pipeline.
  • Ein Ausnahmefilter behandelt eine Ausnahme durch Erzeugen eines Aktionsergebnisses.An exception filter handles an exception by producing an action result.

Die Methode Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting kann die Ausführung des Aktionsergebnisses und der nachfolgenden Ergebnisfilter durch Festlegen von Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel auf true kurzschließen.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. Schreiben Sie beim Kurzschließen in das Antwortobjekt, um zu verhindern, dass eine leere Antwort generiert wird.Write to the response object when short-circuiting to avoid generating an empty response. Beim Auslösen einer Ausnahme in IResultFilter.OnResultExecuting geschieht Folgendes:Throwing an exception in IResultFilter.OnResultExecuting will:

  • Die Ausführung des Aktionsergebnisses und der nachfolgenden Filter wird verhindert.Prevent execution of the action result and subsequent filters.
  • Die ausgelöste Ausnahme wird nicht als erfolgreiches Ergebnis, sondern als Fehler behandelt.Be treated as a failure instead of a successful result.

Wenn die Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted-Methode ausgeführt wird, wurde die Antwort wahrscheinlich bereits an den Client gesendet.When the Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted method runs, the response has likely already been sent to the client. Wenn die Antwort bereits an den Client gesendet wurde, kann sie nicht mehr geändert werden.If the response has already been sent to the client, it cannot be changed further.

ResultExecutedContext.Canceled wird auf true festgelegt, wenn die Ausführung des Aktionsergebnisses durch einen anderen Filter kurzgeschlossen wurde.ResultExecutedContext.Canceled is set to true if the action result execution was short-circuited by another filter.

ResultExecutedContext.Exception wird auf einen Wert ungleich NULL festgelegt, wenn das Aktionsergebnis oder ein nachfolgender Ergebnisfilter eine Ausnahme ausgelöst hat.ResultExecutedContext.Exception is set to a non-null value if the action result or a subsequent result filter threw an exception. Das Festlegen von Exception auf NULL behandelt eine Ausnahme effektiv und verhindert, dass die Ausnahme später in der Pipeline erneut von ASP.NET Core ausgelöst wird.Setting Exception to null effectively handles an exception and prevents the exception from being rethrown by ASP.NET Core later in the pipeline. Beim Behandeln einer Ausnahme in einem Ergebnisfilter gibt es keine zuverlässige Möglichkeit, Daten in eine Antwort zu schreiben.There is no reliable way to write data to a response when handling an exception in a result filter. Wenn ein Aktionsergebnis eine Ausnahme auslöst und die Header bereits an den Client übergeben wurden, gibt es keinen zuverlässigen Mechanismus, einen Fehlercode zu senden.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.

Bei einem IAsyncResultFilter führt ein Aufruf von await next im ResultExecutionDelegate alle nachfolgenden Ergebnisfilter und das Aktionsergebnis aus.For an IAsyncResultFilter, a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. Zum Kurzschließen legen Sie ResultExecutingContext.Cancel auf true fest und rufen den ResultExecutionDelegate nicht auf: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;
        }

    }
}

Das Framework stellt ein abstraktes ResultFilterAttribute bereit, das als Unterklasse verwendet werden kann.The framework provides an abstract ResultFilterAttribute that can be subclassed. Die weiter oben gezeigte Klasse AddHeaderAttribute ist ein Beispiel für ein Ergebnisfilterattribut.The AddHeaderAttribute class shown previously is an example of a result filter attribute.

IAlwaysRunResultFilter und IAsyncAlwaysRunResultFilterIAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter

Die Schnittstellen IAlwaysRunResultFilter und IAsyncAlwaysRunResultFilter deklarieren eine IResultFilter-Implementierung, die für alle Aktionsergebnisse ausgeführt wird.The IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter interfaces declare an IResultFilter implementation that runs for all action results. Dies schließt Aktionsergebnisse ein, die von folgenden Filtern generiert werden:This includes action results produced by:

  • Autorisierungs- und Ressourcenfilter, die einen Kurzschluss bewirkenAuthorization filters and resource filters that short-circuit.
  • AusnahmefilterException filters.

Beispielsweise wird der folgende Filter immer ausgeführt und legt ein Aktionsergebnis (ObjectResult) mit dem Statuscode 422 – Einheit kann nicht bearbeitet werden fest, wenn bei der Inhaltsaushandlung ein Fehler auftritt: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 implementiert IFilterMetadata.IFilterFactory implements IFilterMetadata. Deshalb kann eine IFilterFactory-Instanz an einer beliebigen Stelle in der Filterpipeline als IFilterMetadata-Instanz verwendet werden.Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. Wenn die Runtime den Aufruf des Filters vorbereitet, versucht sie, ihn in eine IFilterFactory umzuwandeln.When the runtime prepares to invoke the filter, it attempts to cast it to an IFilterFactory. Wenn diese Umwandlung gelingt, wird die Methode CreateInstance aufgerufen, um die Instanz IFilterMetadata für den Aufruf zu erstellen.If that cast succeeds, the CreateInstance method is called to create the IFilterMetadata instance that is invoked. Da die exakte Filterpipeline beim Start der Anwendung nicht explizit festgelegt werden muss, wird dadurch ein sehr flexibles Design ermöglicht.This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.

Als weiteres Verfahren zum Erstellen von Filtern kann IFilterFactory mithilfe von benutzerdefinierten Attributimplementierungen implementiert werden: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;
        }
    }
}

Der oben stehende Code kann durch Ausführen des Downloadbeispiels getestet werden:The preceding code can be tested by running the download sample:

  • Rufen Sie die F12-Entwicklungstools auf.Invoke the F12 developer tools.
  • Navigieren Sie zu https://localhost:5001/Sample/HeaderWithFactory.Navigate to https://localhost:5001/Sample/HeaderWithFactory.

Die F12-Entwicklungstools zeigen folgende Antwortheader an, die vom Beispielcode hinzugefügt wurden:The F12 developer tools display the following response headers added by the sample code:

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

Der oben stehende Code erstellt den Antwortheader „internal: My header“.The preceding code creates the internal: My header response header.

In einem Attribut implementierte IFilterFactoryIFilterFactory implemented on an attribute

Filter, die IFilterFactory implementieren, eignen sich in folgenden Fällen:Filters that implement IFilterFactory are useful for filters that:

  • Sie erfordern kein Übergeben von Parametern.Don't require passing parameters.
  • Sie verfügen über Konstruktorabhängigkeiten, die durch DI erfüllt werden müssen.Have constructor dependencies that need to be filled by DI.

TypeFilterAttribute implementiert IFilterFactory.TypeFilterAttribute implements IFilterFactory. IFilterFactory macht die CreateInstance-Methode zum Erstellen einer IFilterMetadata-Instanz verfügbar.IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance lädt den angegebenen Typ aus dem Dienstecontainer (DI).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.");
        }
    }
}

Der folgende Code zeigt drei Ansätze zum Anwenden von [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");
}

Im oben stehenden Code ist das Ergänzen der Methode um [SampleActionFilter] der bevorzugte Ansatz zum Anwenden von SampleActionFilter.In the preceding code, decorating the method with [SampleActionFilter] is the preferred approach to applying the SampleActionFilter.

Verwenden von Middleware in der FilterpipelineUsing middleware in the filter pipeline

Ressourcenfilter funktionieren wie Middleware, sie umschließen alle Ausführungen, die später in der Pipeline enthalten sind.Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. Filter unterscheiden sich jedoch in der Hinsicht von Middleware, dass sie Teil der ASP.NET Core-Runtime sind, was bedeutet, dass sie Zugriff auf ASP.NET Core-Kontext und -Konstrukte haben.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.

Um Middleware als Filter zu verwenden, erstellen Sie einen Typ mit einer Configure-Methode, die die Middleware festlegt, die in die Filterpipeline eingefügt werden soll.To use middleware as a filter, create a type with a Configure method that specifies the middleware to inject into the filter pipeline. Das folgende Beispiel verwendet die Lokalisierungsmiddleware, um die aktuelle Kultur einer Anforderung einzurichten: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);
    }
}

Verwenden Sie das MiddlewareFilterAttribute zum Ausführen der 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}");
}

Middlewarefilter werden zum selben Zeitpunkt in der Filterpipeline wie Ressourcenfilter, vor der Modellbindung und nach dem Rest der Pipeline ausgeführt.Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.

Nächste SchritteNext actions