Click here to Skip to main content
15,900,907 members
Articles / Web Development / ASP.NET / ASP.NET Core

How to Create a Filter for Razor Pages and Razor Views in ASP.NET Core MVC

Rate me:
Please Sign up or sign in to vote.
4.67/5 (2 votes)
5 Sep 2018CPOL1 min read 11.9K   5  
One filter for both razor views and pages

Introduction

I have an ASP.NET Core MVC Web Applications with Razor Views and Razor Pages. In this case, the last ones are the login and account management pages generated by Identity. For all requests, I wanted to be able to access the host domain from the request to customize the style accordingly.

Background

Filters allow you to run code before or after the request is processed. There are some coming out the box, such as, Authorization. On the other hand, you can create your own custom filters.
I found these documents about adding filters in ASP.NET Core. As mentioned in this link, filters for ASP.NET Core MVC views do not apply for Razor Pages.
For Razor Page, I found information here.

Using the Code

As in this case, I use an asynchronous filter I have to implement the OnActionExecutionAsync method of the IAsyncActionFilter interface to apply the filter to Razor Views:

C#
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
   // before the action executes
   var controller = context.Controller as Controller;
   if (controller == null) return;
   controller.ViewData["Host"] = context.HttpContext.Request.Host.Host;
    
   var resultContext = await next();
   // after the action executes
}

On the other hand, for the Razor Pages, I have to implement the IAsyncPageFilter interface:

C#
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context,
                                               PageHandlerExecutionDelegate next)
{
   // Called asynchronously before the handler method is invoked, after model binding is complete.
   var page = context.HandlerInstance as PageModel;
   if (page == null) return;
   page.ViewData["Host"] = context.HttpContext.Request.Host.Host;
   var resultContext = await next();
}

public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
   //Called asynchronously after the handler method has been selected, 
   //but before model binding occurs.  
   await Task.CompletedTask;
}

The resulting filter is the following class:

C#
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Filters
{
    public class HostFilter: IAsyncActionFilter, IAsyncPageFilter
    {
        public async Task OnActionExecutionAsync
               (ActionExecutingContext context, ActionExecutionDelegate next)
        {
           // before the action executes
            var controller = context.Controller as Controller;
            if (controller == null) return;
            controller.ViewData["Host"] = context.HttpContext.Request.Host.Host;

            var resultContext = await next();

            // after the action executes
        }

        public async Task OnPageHandlerExecutionAsync
               (PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
        {
            // Called asynchronously before the handler method is invoked, 
            // after model binding is complete.
            var page = context.HandlerInstance as PageModel;
            if (page == null) return;
            page.ViewData["Host"] = context.HttpContext.Request.Host.Host;
            var resultContext = await next();
        }

        public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
        {
            //Called asynchronously after the handler method has been selected, 
            //but before model binding occurs.
            await Task.CompletedTask;
        }
    }
    }

To enable the filter in the Startup class:

C#
services.AddMvc(options =>
{
    options.Filters.Add(new HostFilter());
});

So, in this way, with one filter, we apply logic to be executed before the handling of any razor view or page in the application.

History

  • 5th September, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --