razor
razor copied to clipboard
Allow @page directive in Razor Components to accept constant strings
Currently the @page directive must specify a route template. The route template must be enclosed in quotes and begin with the '/' character.
I need to be able to use a const string as well.
Is your feature request related to a problem? Please describe.
I want to define my routes in a single place and then reuse them throughout the application, eliminating as many string literals as possible. Without this, refactoring and long-term maintenance becomes a nightmare of Find/Replace.
Describe the solution you'd like
Ideal:
@page @ClientRoutes.Members.ClinicalSupervision
Acceptable:
@page "@ClientRoutes.Members.ClinicalSupervision"
public static class ClientRoutes
{
public static class Members
{
public const string ClinicalSupervision = "/Members/ClinicalSupervision";
}
}
...
private void CancelAsync() => NavigationManager.NavigateTo(ClientRoutes.Members.ClinicalSupervision);
@hellfirehd thanks for contacting us.
Unfortunately, its likely not possible we can do this without significant changes into how the Razor compiler works which this issue alone might not merit the investment.
Pages use string literals because that information gets embedded in several places and is used for several checks. In addition to that, Razor lacks a semantic understanding of the C# code at compile time and it is impossible for it to resolve the constant value to perform the tasks it has to during compilation.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I like example above. But anything is better than magic string, even something so simple like this:
public static class Routes
{
public const string Route1 = "/Hello";
public const string Route2 = "/World/Hi";
}
@page Routes.Hello
Comments written above is correct - it is HARD to maintain this system with magic string. And I find so many times debugging difficulties. With constants it will be better.
Pages use string literals because that information gets embedded in several places and is used for several checks. In addition to that, Razor lacks a semantic understanding of the C# code at compile time and it is impossible for it to resolve the constant value to perform the tasks it has to during compilation.
Could you allow it to be set from the Code Behind?
My issue was closed, as were similar ones over the years. There seems to be resistance to this, but I don't know how it can be justified. Managing something as complicated as routes with the current approach is difficult.
There are all sorts of workarounds on SO ([1], [2]) but none is perfect. It needs to be baked into the compiler/runtime.
Could you allow it to be set from the Code Behind?
That would be fine by me too, but would make assets double in size as we'd need two files for every routable component. There are some examples in those links above. And something like this would be nice too, which effectively places the compile-time constant in the generated codebehind:
@page @ROUTE
@functions { public const string ROUTE = "/Foo"; } // can reference this const from other code
ok, what is the status of this? it was created in 2021.
- https://github.com/dotnet/aspnetcore/issues/28827
- https://github.com/dotnet/aspnetcore/issues/23958
- https://github.com/dotnet/aspnetcore/issues/25589
- https://github.com/dotnet/AspNetCore.Docs/issues/27262
- https://github.com/dotnet/aspnetcore/issues/44352
- https://github.com/dotnet/aspnetcore/issues/23195
- https://github.com/dotnet/aspnetcore/issues/17500
- https://github.com/dotnet/aspnetcore/issues/14098
- https://github.com/dotnet/aspnetcore/issues/13453
- https://github.com/dotnet/aspnetcore/issues/41930
- https://github.com/dotnet/aspnetcore/issues/41827
- ...
@wstaelens Like I said above, this goes back years. There has been resistance to handling it for technical reasons (understandable...), but it's strange given how important this is. Especially given this is c# after all.
I find it staggering that this has not been addressed. A const string is pretty much a string literal anyway. If Razor lacks a semantic understanding of the C# code why not run a pre-processor that runs through and replaces the constants before compiling? There's already something like that happening with the source generated in _razor.g.cs. (Sometimes compile errors refer to these files only which can be very difficult to fix, but that's another issue.)
You can probably just add a Route attribute manually, either from razor file, or from codebehind
@attribute [Route(UrlConst)]
That trick may work for razor components, but not for razor pages. None of the workarounds here or the SO questions I linked above work for Razor Pages.
Please consider this for v9.
This works for RazorPages:
@page
@attribute [RazorCompiledItemMetadata("RouteTemplate", MyConstants.Pages.Foo.Bar)]
But that is unnecessarily complicated, and still has a magic string in it. A better syntax is needed.
+1 to get this done; it conveniently enables declaring your route strings once in the entire application, especially making it easier for parameterless routes.
It's been 4 years since a member said that the compiler infrastructure would need to undergo critical changes to support this feature. Is the status at least any better now to support making this change within a short timeframe without fearing breaking the entire infrastructure?
I had a look at the compiler and I believe it won't require too significant changes. Is it okay if I gave it a go and submitted a PR if it's a manageable case?
yes please @Rekkonnect !
@Rekkonnect If you want to submit a PR for this, we'd be happy to review it! Thanks!
Hi everyone, is there an update for this? We would love to see this resolved especially since there is a waiting PR for it.
Hey I'd love to have the PR merged too; check this comment for more info: https://github.com/dotnet/razor/pull/11805#pullrequestreview-2812981914
Basically the required change would introduce a new kind of token in the language, which is not a decision you can make on the spot so it's being internally discussed. We should be getting an update on this matter within the next few weeks from what I estimate, but I'm not an official source.
On the upside, if this new token kind gets approved, even with modifications, it opens up new possibilities with reducing the usage of @() expressions in other directives, by enabling them to accept simpler and intuitive expressions directly into the syntax. This will be a recurring matter outside the scope of this issue. I'd be glad if those changes got through and we get more QoL improvements like this one in other directives.
It will also help for routing in multi languages scenarri