15

I recently upgraded my website from ASP.NET MVC3 (Razor) to MVC4 (Razor2), and in doing so found what seemed like a breaking change in the Razor view engine.

The scenario (greatly simplified) is shown below.

@model IEnumerable<string>

@{ Layout = null; }

<!DOCTYPE html>

<html>
    <body>
        <div>
              @foreach (var x in Model)
              {
                  @string.Format("Foo bar: {0}", x) // Errors in MVC4/Razor2
              }
        </div>
    </body>
</html>

This works fine in MVC3/Razor, however in MVC4/Razor2 the string.Format line results in an error of:

Unexpected "string" keyword after "@" character. Once inside code, you do not need to prefix constructs like "string" with "@".

If you remove the @, the view engine then demands that you terminate the string.Format line with a semicolon. However, ReSharper then warns (rightly so):

Return value of pure method is not used.

The two fixes I've found for this are either to use <text>:

<text>@string.Format("The value {0}", x)</text>

Or a more curious approach using @:@:

@:@string.Format("The value {0}", x)

Is this a known and documented change in the Razor view engine?

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
  • 1
    The warning from resharper in this case is incorrect, and should be reported to them or suppressed. There is a difference between the C# code generated at design time and in runtime, the runtime c# will wrap the string.format with another method call, and hence it's totally valid. Resharper should ignore this class of errors (and so can you) – Yishai Galatzer Oct 14 '13 at 17:09

2 Answers2

16

Seems like a bug. It works with String:

@foreach (var x in Model)
{
    @String.Format("Foo bar: {0}", x)
}
polybios
  • 1,159
  • 8
  • 20
  • 1
    Most likely because `String` is not a keyword. A bit odd behaviour anyway, I'm not sure why it would allow `@` inside code blocks to begin with. – Joachim Isaksson Mar 21 '13 at 11:19
  • @ has to be allowed because it's valid C#; it's used to declare verbatim strings; ie. strings in which special characters are reproduced exactly. So, `string msg = "test \t message";` replaces the `\t` with a tab, but `string msg = @"test \t message";` leaves it as `"\t"`. – anaximander Mar 21 '13 at 13:50
  • @ does not have to be allowed, and is not in Razor. @ before an identifier is used to override keywords with type names. – Yishai Galatzer Oct 14 '13 at 17:08
5

This is indeed a bug we decided not to fix, note that the syntax is incorrect as there is no transition between C# and markup in this case.

I understand that resharper shows a warning here but I believe the warning is wrong.

Here is the bug for future reference https://aspnetwebstack.codeplex.com/workitem/458

Yishai Galatzer
  • 8,791
  • 2
  • 32
  • 41