Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom ActionFilterAttribute on Razor PageModel Get method #2981

Closed
fmaeseele opened this issue Mar 20, 2018 · 5 comments
Closed

Custom ActionFilterAttribute on Razor PageModel Get method #2981

fmaeseele opened this issue Mar 20, 2018 · 5 comments

Comments

@fmaeseele
Copy link

Hi,

I'm trying to get a custom ActionFilterAttribute to get working on the Get method of my Razor Pages.
Starting with a simple .NetCore Web project, I created a custom ActionFilterAttribute as :

`
public class MyCustomActionFilterAttribute : ActionFilterAttribute
{
///


/// Title of the current item
///

public string Title { get; set; }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
          // This method is NEVER called!!
        System.Diagnostics.Debugger.Break();
    }
}

`

Then I use it in my Index.cshtml.cs :

public class IndexModel : PageModel { [MyCustomActionFilter(Title ="My Title", Order =1)] public void OnGet() { } }

But the method OnActionExecuting is never called.
What am I missing ?

Regards.
François
TestCustomActionFilterAttribute.zip

@pranavkm
Copy link
Contributor

@fmaeseele page filters can only be applied to a page model, and not individual handler methods. Additionally, you need to use IPageFilter when working with a Razor Page. IActionFilter \ ActionFilterAttribute only applies to controller actions. Unfortunately the docs for page filters is a bit lacking, I'll add some details in a follow up comment

@pranavkm
Copy link
Contributor

Razor Page Filters

Analogous to action filters, IPageFilter or IAsyncPageFilter surround the selection and execution of page handlers. Filters on Razor Page or Razor Page models can only be applied at the type level i.e. you may only apply an IPageFilter or an IAsyncPageFilter to the model type and not to individual handler methods.
Here's a sample page filter:

public class SamplePageFilter : IPageFilter
{
    public void OnPageHandlerSelected(PageHandlerSelectedContext  context)
    {
        // do something during page handler selection.
    }

    public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
    {
        // do something after handler selection, but before a handler method executes.
    }
    
    public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
    {
        // do something after a handler method executes.
    }
}

The PageModel type implements an IPageFilter and IAsyncPageFilter. Applications may override these methods in their model types to provide an implementation. Example:

public class Index : PageModel
{
    public string Title { get; private set; }

    public override void OnPageHandlerExecuting(PageHandlerExecutingContext context)
    {
        Title = "Title set in handler executing";
    }
}

Page filters can be applied globally by adding to MvcOptions.Filters e.g.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new CustomPageFilter());
    });
}

They may also be applied to a subset of pages by using AddFolderApplicationModelConvention:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.AddFolderApplicationModelConvention("/MyDir", model => model.Filters.Add(new CustomPageFilter()));
        });
}

@fmaeseele
Copy link
Author

Hi @pranavkm ,

Thank you very much for your quick and clear answer.
I finally ended up with your IPageFilter solution for my filter to intercept OnGet() requests.

That said, this is unfortunate that we cannot filter on a specific handler method by putting the attribute directly on it. Thanks to RazorPages, we may not need controller in most of the case. So it could be useful to be able to use a kind of action attribute on a specific method handler.

Thanks again.

Best Regards,
François

@freerider7777
Copy link

Razor pages is a recommended way of development... You just have to rewrite all your staff - filters, attributes and so on... :(

@GocePetrovski
Copy link

GocePetrovski commented Jul 26, 2018

How do I suppress exception?

        public override void OnPageHandlerExecuted(PageHandlerExecutedContext context) {
            if(context.Exception != null && context.Exception is AMyException) {
                // do something..
                context.ExceptionHandled = true;
            } 
        }

produces empty page.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants