razor icon indicating copy to clipboard operation
razor copied to clipboard

Improve string handling support

Open 333fred opened this issue 3 years ago • 15 comments

There are a few issues around strings in the razor compiler currently:

  1. Interpolated strings that have " characters in interpolation holes are not handled correctly.
  2. Raw string literals from C# 11 are not supported correctly.

/cc @DamianEdwards.

333fred avatar Aug 02 '22 23:08 333fred

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.

V0ldek avatar Nov 30 '22 16:11 V0ldek

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!

TimPurdum avatar May 28 '23 21:05 TimPurdum

Do we have an update on this? Would be nice if this could make it in .NET 8 GA release.

lofcz avatar Jul 25 '23 20:07 lofcz

Any news on this?

JohnyL avatar Aug 15 '23 18:08 JohnyL

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

coderbarncb avatar Aug 16 '23 09:08 coderbarncb

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 avatar Aug 16 '23 10:08 V0ldek

@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 avatar Aug 19 '23 09:08 gragra33

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

coderbarncb avatar Aug 22 '23 12:08 coderbarncb

@achselschweisz I don't disagree however, for now, there is a working solution.

gragra33 avatar Aug 25 '23 03:08 gragra33

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

V0ldek avatar Aug 25 '23 14:08 V0ldek

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

cameronbell97 avatar Sep 18 '23 20:09 cameronbell97

I'm wondering if this is related to https://github.com/dotnet/aspnetcore/issues/4976 - String interpolation with nested quotes breaks Razor blocks.

PoseidonEnergy avatar Feb 02 '24 21:02 PoseidonEnergy

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.

333fred avatar Feb 02 '24 21:02 333fred

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.

Tragen avatar Mar 01 '24 22:03 Tragen

Yes. My prototype also supports binary literals as well.

333fred avatar Mar 03 '24 06:03 333fred

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. Screenshot 2024-04-09 at 10 35 19 AM

codymullins avatar Apr 09 '24 14:04 codymullins

Looks like this issue is finally being resolved! Is there a release soon that this fix will be tied to?

NoahS2003 avatar Aug 21 '24 20:08 NoahS2003

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.

333fred avatar Aug 21 '24 20:08 333fred

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:

Image

JohnyL avatar Nov 03 '24 20:11 JohnyL

This is an opt-in feature. You need to add something like <Features>use-roslyn-tokenizer=true</Features> to your csproj.

jjonescz avatar Nov 04 '24 09:11 jjonescz

@jjonescz I've added this line, but still same error.

Image

JohnyL avatar Nov 04 '24 14:11 JohnyL

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

jjonescz avatar Nov 04 '24 14:11 jjonescz

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.

333fred avatar Nov 04 '24 17:11 333fred

@jjonescz can this <Features>use-roslyn-tokenizer=true</Features> be added to Directory.build.props to enable in all projects?

codymullins avatar Nov 05 '24 15:11 codymullins

Certainly.

333fred avatar Nov 05 '24 16:11 333fred

@jjonescz Thanks for a tip! Still doesn't work:

Image Image

JohnyL avatar Nov 10 '24 14:11 JohnyL

@JohnyL you will need VS 17.13p2 to see it live in the ide.

333fred avatar Nov 10 '24 16:11 333fred

@333fred Beg your pardon, but does such version exists for now? I've got 17.12.p5.

JohnyL avatar Nov 10 '24 19:11 JohnyL

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

333fred avatar Nov 10 '24 20:11 333fred

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

jjonescz avatar Nov 11 '24 09:11 jjonescz