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)
{
var controller = context.Controller as Controller;
if (controller == null) return;
controller.ViewData["Host"] = context.HttpContext.Request.Host.Host;
var resultContext = await next();
}
On the other hand, for the Razor Pages, I have to implement the IAsyncPageFilter
interface:
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context,
PageHandlerExecutionDelegate next)
{
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)
{
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)
{
var controller = context.Controller as Controller;
if (controller == null) return;
controller.ViewData["Host"] = context.HttpContext.Request.Host.Host;
var resultContext = await next();
}
public async Task OnPageHandlerExecutionAsync
(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
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)
{
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