Skip to content

Latest commit

 

History

History
196 lines (111 loc) · 11.3 KB

File metadata and controls

196 lines (111 loc) · 11.3 KB
title author description monikerRange ms.author ms.date uid
Filter methods for Razor Pages in ASP.NET Core
tdykstra
Learn how to create filter methods for Razor Pages in ASP.NET Core.
>= aspnetcore-2.1
tdykstra
2/18/2020
razor-pages/filter

Filter methods for Razor Pages in ASP.NET Core

:::moniker range=">= aspnetcore-3.0"

By Rick Anderson

Razor Page filters xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter and xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter allow Razor Pages to run code before and after a Razor Page handler is run. Razor Page filters are similar to ASP.NET Core MVC action filters, except they can't be applied to individual page handler methods.

Razor Page filters:

  • Run code after a handler method has been selected, but before model binding occurs.
  • Run code before the handler method executes, after model binding is complete.
  • Run code after the handler method executes.
  • Can be implemented on a page or globally.
  • Cannot be applied to specific page handler methods.
  • Can have constructor dependencies populated by Dependency Injection (DI). For more information, see ServiceFilterAttribute and TypeFilterAttribute.

While page constructors and middleware enable executing custom code before a handler method executes, only Razor Page filters enable access to xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel.HttpContext and the page. Middleware has access to the HttpContext, but not to the "page context". Filters have a xref:Microsoft.AspNetCore.Mvc.Filters.FilterContext derived parameter, which provides access to HttpContext. Here's a sample for a page filter: Implement a filter attribute that adds a header to the response, something that can't be done with constructors or middleware. Access to the page context, which includes access to the instances of the page and it's model, are only available when executing filters, handlers, or the body of a Razor Page.

View or download sample code (how to download)

Razor Page filters provide the following methods, which can be applied globally or at the page level:

  • Synchronous methods:

    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerSelected%2A : Called after a handler method has been selected, but before model binding occurs.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerExecuting%2A : Called before the handler method executes, after model binding is complete.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerExecuted%2A : Called after the handler method executes, before the action result.
  • Asynchronous methods:

    • xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter.OnPageHandlerSelectionAsync%2A : Called asynchronously after the handler method has been selected, but before model binding occurs.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter.OnPageHandlerExecutionAsync%2A : Called asynchronously before the handler method is invoked, after model binding is complete.

Implement either the synchronous or the async version of a filter interface, not both. The framework checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface's method(s). If both interfaces are implemented, only the async methods are called. The same rule applies to overrides in pages, implement the synchronous or the async version of the override, not both.

Implement Razor Page filters globally

The following code implements IAsyncPageFilter:

[!code-csharpMain]

In the preceding code, ProcessUserAgent.Write is user supplied code that works with the user agent string.

The following code enables the SampleAsyncPageFilter in the Startup class:

[!code-csharpMain]

The following code calls xref:Microsoft.AspNetCore.Mvc.ApplicationModels.PageConventionCollection.AddFolderApplicationModelConvention* to apply the SampleAsyncPageFilter to only pages in /Movies:

[!code-csharpMain]

The following code implements the synchronous IPageFilter:

[!code-csharpMain]

The following code enables the SamplePageFilter:

[!code-csharpMain]

Implement Razor Page filters by overriding filter methods

The following code overrides the asynchronous Razor Page filters:

[!code-csharpMain]

Implement a filter attribute

The built-in attribute-based filter xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter.OnResultExecutionAsync* filter can be subclassed. The following filter adds a header to the response:

[!code-csharpMain]

The following code applies the AddHeader attribute:

[!code-csharpMain]

Use a tool such as the browser developer tools to examine the headers. Under Response Headers, author: Rick is displayed.

See Overriding the default order for instructions on overriding the order.

See Cancellation and short circuiting for instructions to short-circuit the filter pipeline from a filter.

Authorize filter attribute

The Authorize attribute can be applied to a PageModel:

[!code-csharpMain]

:::moniker-end

:::moniker range="< aspnetcore-3.0"

By Rick Anderson

Razor Page filters xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter and xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter allow Razor Pages to run code before and after a Razor Page handler is run. Razor Page filters are similar to ASP.NET Core MVC action filters, except they can't be applied to individual page handler methods.

Razor Page filters:

  • Run code after a handler method has been selected, but before model binding occurs.
  • Run code before the handler method executes, after model binding is complete.
  • Run code after the handler method executes.
  • Can be implemented on a page or globally.
  • Cannot be applied to specific page handler methods.

Code can be run before a handler method executes using the page constructor or middleware, but only Razor Page filters have access to xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel.HttpContext%2A. Filters have a xref:Microsoft.AspNetCore.Mvc.Filters.FilterContext derived parameter, which provides access to HttpContext. For example, the Implement a filter attribute sample adds a header to the response, something that can't be done with constructors or middleware.

View or download sample code (how to download)

Razor Page filters provide the following methods, which can be applied globally or at the page level:

  • Synchronous methods:

    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerSelected%2A : Called after a handler method has been selected, but before model binding occurs.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerExecuting%2A : Called before the handler method executes, after model binding is complete.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IPageFilter.OnPageHandlerExecuted%2A : Called after the handler method executes, before the action result.
  • Asynchronous methods:

    • xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter.OnPageHandlerSelectionAsync%2A : Called asynchronously after the handler method has been selected, but before model binding occurs.
    • xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter.OnPageHandlerExecutionAsync%2A : Called asynchronously before the handler method is invoked, after model binding is complete.

Note

Implement either the synchronous or the async version of a filter interface, not both. The framework checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface's method(s). If both interfaces are implemented, only the async methods are called. The same rule applies to overrides in pages, implement the synchronous or the async version of the override, not both.

Implement Razor Page filters globally

The following code implements IAsyncPageFilter:

[!code-csharpMain]

In the preceding code, xref:Microsoft.Extensions.Logging.ILogger is not required. It's used in the sample to provide trace information for the application.

The following code enables the SampleAsyncPageFilter in the Startup class:

[!code-csharpMain]

The following code shows the complete Startup class:

[!code-csharpMain]

The following code calls AddFolderApplicationModelConvention to apply the SampleAsyncPageFilter to only pages in /subFolder:

[!code-csharpMain]

The following code implements the synchronous IPageFilter:

[!code-csharpMain]

The following code enables the SamplePageFilter:

[!code-csharpMain]

Implement Razor Page filters by overriding filter methods

The following code overrides the synchronous Razor Page filters:

[!code-csharpMain]

Implement a filter attribute

The built-in attribute-based filter xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter.OnResultExecutionAsync%2A filter can be subclassed. The following filter adds a header to the response:

[!code-csharpMain]

The following code applies the AddHeader attribute:

[!code-csharpMain]

See Overriding the default order for instructions on overriding the order.

See Cancellation and short circuiting for instructions to short-circuit the filter pipeline from a filter.

Authorize filter attribute

The Authorize attribute can be applied to a PageModel:

[!code-csharpMain]

:::moniker-end