3
votes

I have a simple ASP.Net Core 3.1 Razor Pages project. In the Index.cshtml I have changed @page to @page "{handler?}" so I can use routing-based handler methods. That works fine. The issue is, now this page becomes a catch-all route for any url. For example, I can go to http://mysite/foo and it will not give a 404 anymore. How can I make it return a 404 if the handler method doesn't exist?

1

1 Answers

0
votes

I dont know if this is best solution:

public class IsValidPageHandler : ActionMethodSelectorAttribute 
    {
        public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
        {
            if (!routeContext.RouteData.Values.ContainsKey("handler") 
                || routeContext.RouteData.Values["handler"] == null 
                || ((CompiledPageActionDescriptor) action).HandlerMethods.Any(f=>routeContext.RouteData.Values["handler"].ToString().Equals(f.Name, StringComparison.OrdinalIgnoreCase)))
                return true;
            else
                return false;
        }
    }

and then

...
endpoints.MapRazorPages();

var actions = app.ApplicationServices.GetService<IActionDescriptorCollectionProvider>();
foreach (var item in actions.ActionDescriptors.Items.Where(f => f.AttributeRouteInfo != null && f.AttributeRouteInfo.Template.Contains("{handler?}")).ToList())
    item.ActionConstraints.Add(new IsValidPageHandler());
...

other solution create a Filter and add Filter but that one happens later in a pipe. within you have context with context.HandlerMethod and RouteData which you can compare similar to above

public class CustomRazorPageFilter : IAsyncPageFilter
{
    public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
    { 
    ... 
    }
...