razor
razor copied to clipboard
Improve string handling support
There are a few issues around strings in the razor compiler currently:
- Interpolated strings that have
"characters in interpolation holes are not handled correctly. - Raw string literals from C# 11 are not supported correctly.
/cc @DamianEdwards.
Raw string literals would be really useful for including code snippets in Blazor pages, currently you have to use verbatim strings and excape all " while also making sure indentation matches.
This is really annoying, I expect C# features to work in razor files and don't want to keep track of what features aren't implemented, like raw string literals. Please update soon!
Do we have an update on this? Would be nice if this could make it in .NET 8 GA release.
Any news on this?
My current workaround for this issue (raw string literals) is to
- use the code-behind approach for razor components
- use some other class reference
This, however, adds more clutter to an existing project when all I need is a tiny file for a simple component...
My current workaround for this issue (raw string literals) is to
- use the code-behind approach for razor components
- use some other class reference
This is unacceptable for my use case. The whole point of passing raw string literals as arguments to a component is readability, the fact that I can read the cshtml top to bottom and see the entire content.
At that point I might just as well use regular verbatim strings and escape everything.
@V0ldek @achselschweisz @JohnyL @lofcz @TimPurdum @333fred
You can use string literals in your razor (.Net 7) - see below:
@{
string literal = $@"""Value {Value}""";
<div>@literal</div>
}
or, you can inline it:
@{<div>@($@"""Value {Value}""")</div>}
Here is another working example:
@{<pre>@(@"
{
""Id"": null,
""FName"": ""create"",
""LName"": ""Denny"",
""DateofJoining"": null,
""Date"": ""2023-08-01T00:00:00"",
""CreatedBy"": ""ICC0000389"",
""levels"": {
""RoleId"": ""0"",
""RoleName"": ""select"",
""IsActive"": false,
""CreatedDate"": null,
""CreatedBy"": ""Admin""
},
""functionalities"": [{
""levelID"": 0,
""levelName"": ""create""
}
],
""functionalityList"": []
}")</pre>}
It may not be ideal, however, it's an extra 3 characters for a working solution until a better solution is available.
However, this fails:
@{<pre>@($$"""
{
"Id": null,
"FName": "create",
"LName": "Denny",
"DateofJoining": null,
"Date": "2023-08-01T00:00:00",
"CreatedBy": "ICC0000389",
"levels": {
"RoleId": "0",
"RoleName": "select",
"IsActive": false,
"CreatedDate": null,
"CreatedBy": "Admin"
},
"functionalities": [{
"levelID": 0,
"levelName": "create"
}
],
"functionalityList": []
}
"""
)</pre>}
with the following compile error:
RZ1000 Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
@gragra33 I think we all want raw string literals spread over several lines to work in razor components. All workarounds, including the one I posted myself, are basically suboptimal. Having to duplicate quotes and whatnot defeats the purpose of this excellent C#11 feature, I am afraid.
@achselschweisz I don't disagree however, for now, there is a working solution.
@achselschweisz I don't disagree however, for now, there is a working solution.
Depends on what you mean by "solution". The problem here is that we want raw string literals, which are only materially different from other string tokens when they're multiline. Your comment is basically "but you can use normal strings just fine". Sure, not what we're asking for, though.
Is there any idea on when this might be implemented? When this issue was opened the feature was still only in preview/rc .NET builds but we're fast approaching the 1-year mark of this feature being in the official latest .NET release. It would be great to have this available for razor files particularly for Blazor development
I'm wondering if this is related to https://github.com/dotnet/aspnetcore/issues/4976 - String interpolation with nested quotes breaks Razor blocks.
Correct. When we start taking advantage of Roslyn's lexer in Razor, that issue should also be resolved.
I know you all have been patiently waiting for progress here, and this is next on my list of issues to work on. I don't realistically expect that I'll get it in for 17.10, but we know how we're going to approach this now and I expect that it'll be in 17.11.
When you star with Roslyn's lexer, will this also solve the problem that I cannot use underscores in numbers?
@page "/customer/{id:int:min(1):max(2_000_000_000)}"
this doesn't work.
Yes. My prototype also supports binary literals as well.
I seem to be encountering some variation of this issue. With feedback from Egil Hanson and Peter Morris, I noticed you can get this "working" using four quotation marks:
<PureCode Language="@PureCode.Razor">
@(""""
<PureBanner Accent="Accent.Brand">
This is a branded banner.
</PureBanner>
"""")
</PureCode>
However, after changing the file a bit more, this breaks. Re-adding them one at a time seems to work temporarily.
Looks like this issue is finally being resolved! Is there a release soon that this fix will be tied to?
We expect that you'll be able to opt-in to the new lexer during the initial 9.0 release. Based on feedback from that, we'll look at turning it on by default in a later SDK minor update.
As of .NET 9 RC2, raw string literals do work, but... only in the case of separate model class.
If you use @functions, they do not work:
This is an opt-in feature. You need to add something like <Features>use-roslyn-tokenizer=true</Features> to your csproj.
@jjonescz I've added this line, but still same error.
Sorry @JohnyL, it looks like the PR adding the new tokenizer didn't make it into .NET 9.0.1xx SDK, you could try a (not officially released) 9.0.2xx SDK from https://github.com/dotnet/sdk/blob/main/documentation/package-table.md
We will be posting a blog about this change and documenting how to enable it for testing soon; as Jan said, it didn't quite make 9.0.1xx, but will be available in 9.0.2xx. It'll be off by default first, as it's a large change and we want to make sure that it's working well for all users before turning it on by default.
@jjonescz can this <Features>use-roslyn-tokenizer=true</Features> be added to Directory.build.props to enable in all projects?
Certainly.
@jjonescz Thanks for a tip! Still doesn't work:
@JohnyL you will need VS 17.13p2 to see it live in the ide.
@333fred Beg your pardon, but does such version exists for now? I've got 17.12.p5.
@333fred Beg your pardon, but does such version exists for now? I've got 17.12.p5.
Not yet, no. As I said, we'll have a blog post out with instructions on how to try it out when it's available.
@jjonescz Thanks for a tip! Still doesn't work:
Building the solution or running dotnet build from the command line should work with that SDK. But yeah, IDE will show errors as Fred says.