2

When migrating a view (.cshtml):

code

@{
  var attributesDanger = (object)new { @class = "text-danger" };
  var attributesLabel = (object)new { @class = "control-label" };
}

I got all these errors:

errors

Invalid expression Term '='
"class" is a reserved word an cannot be used in implicit expressions. An explicit expression("@()") must be used
Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.

Is there any syntax difference between .Net Framework and .Net Core that would cause these errors?

podrick
  • 35
  • 6
Matt R
  • 37
  • 5
  • BTW, your `(object)`-casts shouldn't be necessary - I assume you're just passing `attributesDanger` and `attributesLabel` into the `htmlAttributes:` parameter of HTML-Helpers? – Dai Jul 11 '23 at 17:36
  • A comment on [this question](https://stackoverflow.com/questions/67647688/asp-net-core-5-error-class-is-a-reserved-word-and-cannot-be-used-in-implicit) suggests this is a low priority bug and offers a workaround (use `@@` instead of `@`) – devlin carnate Jul 11 '23 at 17:47

2 Answers2

4
  • As you're probably aware, C# (in .cs files) lets you use @ as an identifier prefix to let you use C#'s reserved keywords as identifiers, e.g. public class @float {}.

    • Prior to ASP.NET Core (i.e. ASP.NET MVC 1.x through 4.x), the HTML-Helpers supported using C# anonymously-typed objects to specify HTML attribute names, including @class for HTML's class="" attribute:, e.g. new { hidden = true, title = "tooltip text", @class = "foobar" }
    • However, ASP.NET Core's Razor does not allow using @ in @class here, even though it's still within a C# code-block. I don't know why this change was made in ASP.NET Core, but Razor's built-in support for HTML attributes and TagHelpers makes using anonymous-types (e.g. new { attribName = "value" }) somewhat obsolete.
  • In Razor, the @ character is also reserved to denote the start of a Razor code-block or render-expression; e.g.:

    • <p>@paragraphText</p>
    • @{ await DoSomethingAsync(); }
    • @if( expr ) { <text>raw HTML here</text> }
  • Because Razor's parser is greedy w.r.t. the @ character, it means you need to escape the @ when using @ in literal output, such as in a CSS @media-query in an inline <style> element, or when putting an e-mail address in Razor HTML: e.g. <a href="mailto:billg@@example.com">e-mail me</a>.

    • As far as I can tell, since ASP.NET Core's own flavour of Razor launched you also need to escape @ if it's used inside C# code within Razor code-blocks or render-expressions even though it isn't a literal.

...so change @class to @@class, like so:

(Also, you don't/shouldn't need the (object)-cast)

@{
  var attributesDanger = new { @@class = "text-danger" };
  var attributesLabel  = new { @@class = "control-label" };
}

However, as you're now using ASP.NET Core, you should avoid using the old HTML-Helpers and instead use Razor's built-in support for HTML attributes (this is independent of Tag-Helpers, btw):

<div class="@( someBool ? "text-danger" : "control-label" )"></div>

Or:

@{
    const String CLASS_DANGER = "text-danger";
    const String CLASS_LABEL  = "control-label";
    String cssClass = someBool ? CLASS_DANGER  : CLASS_LABEL;
}

<div class="@cssClass"></div>
Dai
  • 141,631
  • 28
  • 261
  • 374
0

I cannot comment yet, so try changing this:

var attributesDanger = (object)new { @class = "text-danger" }

to this:

var attributesDanger = new { @class = 'text-danger' }

i.e. remove (object) and use single quotes.

I don't really see where you did anything wrong.

podrick
  • 35
  • 6
  • Unfortunately that did not change anything – Matt R Jul 11 '23 at 16:39
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 13 '23 at 18:46