In 2.1 we're going to allow routes specified in a page to use absolute route template syntax. That looks like:
@page "~/Example"
or
@page "/Another/Example"
The key part is the ~/ or /. This makes the route template an absolute template, meaning that it will not be concatenated with the pages path.
Example: (in /Pages/Blog/About)
@page "AboutMe"
This page will execute when the URL path is /Blog/About/AboutMe. In 2.0 the /Blog/About part of the route template is implied and cannot be overridden.
In 2.1 we're adding this capability using the familiar syntax used elsewhere in MVC
Example: (in /Pages/Blog/About)
@page "/AboutMe"
OR
@page "~/AboutMe"
This page will execute when the URL path is /AboutMe. What you see is what you get. This example provides an totally different route template that replaces the default. This was not supported in 2.0
We decided to do something different than what was original posted in this issue for technical/design reasons. What was originally explained here would require us to compile all pages at startup time before MVC could respond to any requests.
The approach used for routing in pages is specifically designed to work based on a simple parse of the document, without the need to compile and run the code. This allows us to quickly build a route table for a large number of pages.
We're improving the capabilities that Razor has to participate in the build in 2.1, and doing a lot to make it fast too. We're very hopeful that what we're doing with this is going to be a good change for Razor and that most of our developer base will love it. If that's the case, then we'd have the ability to do some of the things detailed in the original issue.
Support attribute routes on Razor Pages and Page Models
Based on feedback, we want to support customizing Razor Pages routes using attribute routing. This will require we discover and compile all pages ahead of building the route table
Would rely on #6562 to allow attributes to be specified in the Razor Page file. E.g.:
@page
@attribute Route("custom")
@* GET /custom *@
Hello, World!
The attributes could be placed on the PageModel class directly, and/or on the handler methods, with very similar behavior to attribute routing on controllers and actions (cascading, overriding, composition, etc.). The routes would be additive to the implied routes (we can debate that). E.g.:
c#
[Route("custom")]
public class MyPageModel : PageModel
{
// GET /custom/handler/foo
[HttpGet("handler/{param}")]
public IActionResult CustomHandlerMethod(string param)
{
...
}
}
The function-like syntax is weird little bit. It would be nice & simpler if we can use:
@page
@route "custom"
@* GET /custom *@
Hello, World!
So we plans to support using "~/Foo" and /Foo as overrides. So any page can have full control over its route.
I fully support adding routing to the PageModel and to the form itself, because I have routes that I would like to use which inject a dependency into the route path.
For example. A route of: [Route("path/to/{userId}/page_name/{itemId}")] -> this passes in userId and itemId as parameters to the method.
Currently there is no way that I've found to inject userId into a Razor Page. This is important because we have dependent "pages" that need userId (for example) to be further up the path.
This forces me to have to go down to utilizing Controllers/Views as opposed to Razor Pages (which would work in 90+% of the time).
Currently there is no way that I've found to inject userId into a Razor Page. This is important because we have dependent "pages" that need userId (for example) to be further up the path.
@ahazelwood, you can use AddPageRoute on RazorPagesOptions.Conventions to do this. For e.g. https://github.com/aspnet/Mvc/blob/47287c508ee43c4f30b8000400fda1b01f68bfe2/test/WebSites/RazorPagesWebSite/Startup.cs#L23
@pranavkm thanks, I was aware of this, but in an ideal world, I would like to be able to do this within the Razor Page itself as this is cleaner, in my opinion, way of having the route information tied to where the work is being done. This way as we add/remove functionality in the future, this is handled automatically. This would especially be helpful in the future as we look at moving to more of a modular "features" approach to building our sites.
@DamianEdwards and others watching this issue, I updated the original post to provide more details and context.
@DamianEdwards Thanks for adding this in 2.1.0. This helps out tremendously.
For anyone that finds this in the future, you can now define routes on the @page directive. For example: @page "/some/unrelated/{routeid}/child" and references to /some/unrelated/blah/child will work correctly.
Most helpful comment
The function-like syntax is weird little bit. It would be nice & simpler if we can use: