Skip to content

Allow @page directive in Razor Components to accept constant strings #7519

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

Open
hellfirehd opened this issue Aug 18, 2021 · 18 comments · May be fixed by #11805
Open

Allow @page directive in Razor Components to accept constant strings #7519

hellfirehd opened this issue Aug 18, 2021 · 18 comments · May be fixed by #11805
Labels
area-blazor area-compiler Umbrella for all compiler issues enhancement Small improvement request untriaged
Milestone

Comments

@hellfirehd
Copy link

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);
@javiercn javiercn added area-blazor enhancement Small improvement request area-compiler Umbrella for all compiler issues labels Aug 19, 2021
@javiercn
Copy link
Member

@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.

@javiercn javiercn added this to the Backlog milestone Aug 19, 2021
@ghost
Copy link

ghost commented Aug 19, 2021

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.

@denisz1
Copy link

denisz1 commented Oct 3, 2022

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.

@hellfirehd
Copy link
Author

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?

@lonix1
Copy link

lonix1 commented Oct 4, 2022

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

@wstaelens
Copy link

ok, what is the status of this? it was created in 2021.

@lonix1
Copy link

lonix1 commented Oct 4, 2022

@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.

@mkArtakMSFT mkArtakMSFT transferred this issue from dotnet/aspnetcore Oct 12, 2022
@chsienki chsienki transferred this issue from dotnet/razor-compiler Oct 28, 2022
@ghost ghost added the untriaged label Oct 29, 2022
@michaelcsikos
Copy link

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.)

@Dreamescaper
Copy link

You can probably just add a Route attribute manually, either from razor file, or from codebehind
@attribute [Route(UrlConst)]

@lonix1
Copy link

lonix1 commented Feb 29, 2024

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.

@lonix1
Copy link

lonix1 commented Apr 6, 2024

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.

@Rekkonnect
Copy link

+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?

@Rekkonnect
Copy link

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?

@wstaelens
Copy link

yes please @Rekkonnect !

@chsienki
Copy link
Member

@Rekkonnect If you want to submit a PR for this, we'd be happy to review it! Thanks!

@Rekkonnect Rekkonnect linked a pull request Apr 30, 2025 that will close this issue
@anil-sezer
Copy link

Hi everyone, is there an update for this? We would love to see this resolved especially since there is a waiting PR for it.

@Rekkonnect
Copy link

Hey I'd love to have the PR merged too; check this comment for more info:
#11805 (review)

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor area-compiler Umbrella for all compiler issues enhancement Small improvement request untriaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants