Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

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

0.00/5 (No votes)
5 Sep 2018 1  
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:

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:

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:

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:

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here