Search code examples
c#asp.net-corerazorrazor-pagesaction-filter

ActionFilter equivalent in Asp.net Core Razor Pages


First off all,I know there is no Action Filter in asp.net core razor pages.But I am searching to find a mechanism that works similar. What I am trying to achieve is to apply filter based on handler methods.When I try to use pagefilter, it is applied to all methods.Is there any method/way to exclude some handler methods on the same page ?

To clarify question I added some examples.

Here is example pagefilter

public class FormValidatorRazor : IAsyncPageFilter
{
    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        if (context.HttpContext.Request.Method.Equals("POST") || context.HttpContext.Request.Method.Equals("PUT"))
        //code removed for brevity
 }

Here is how I apply it to the project

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages().AddMvcOptions(options =>
    {
        options.Filters.Add(new FormValidatorRazor());
        //code removed for brevity
    }
}

Here is example handler methods.

public async Task<IActionResult> OnPostUpdate(ExModel model)
{
}

public async Task<IActionResult> OnPostEdit(ExModel model)
{
}

I want my filter to be applied to OnPostUpdate but not to OnPostEdit.How can I achieve that behaviour ?


Solution

  • The PageHandlerExecutingContext parameter passed in to OnPageHandlerExecutionAsync provides everything you need to achieve this. Here's an example that shows the specifics:

    public async Task OnPageHandlerExecutionAsync(
        PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        if (context.HandlerMethod?.Name == "Update")
        {
            // Running inside a handler method named "Update".
        }
    
        // ...
    }
    

    HandlerMethod is non-null when a handler method is being executed. It provides these properties, that might be of interest:

    Alternatively, if you'd like to opt-out at the handler level, you could use a custom attribute and check for its existence in OnPageHandlerExecutionAsync:

    public class SomePageFilterExcludeAttribute : Attribute { }
    

    [SomePageFilterExclude]
    public void OnPostUpdate() { }
    

    public async Task OnPageHandlerExecutionAsync(
        PageHandlerExecutingContext ctx, PageHandlerExecutionDelegate next)
    {
        var isHandlerExcluded = ctx.HandlerMethod?.MethodInfo?.
            GetCustomAttributes(typeof(SomePageFilterExcludeAttribute), false).Any() == true;
    
        // ...
    }