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
@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
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:
```C#
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:
```C#
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.
```C#
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`:
```C#
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AddFolderApplicationModelConvention("/MyDir", model => model.Filters.Add(new CustomPageFilter()));
});
}
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
Razor pages is a recommended way of development... You just have to rewrite all your staff - filters, attributes and so on... :(
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.
Most helpful comment
Razor pages is a recommended way of development... You just have to rewrite all your staff - filters, attributes and so on... :(