Rendering JavaScript using Razor, including non-escaped characters

13 Feb

NOTE: This post uses a variant of the LocalResX extension method written and described in an earlier post, only suited for usage with HtmlHelper:

I wanted to render a JavaScript array, which was built of several server side resources. Similar to Classic ASP, MVC easily supports embedding client and server side code. This looks something like this:

1: var myArray = [ @for(int i = 1; i <= 10; i++)
2:                  {
3:                     @string.Format("'{0}'", Html.LocalResX("Item" + i.ToString()));
4:                  } ];

However, there were two problems:

  1. I needed a comma in between the client array items.
  2. The apostrophe (and eventually the comma too) are rendered as encoded escaped characters.

The thing is, I had no idea how to render simple text (i.e. a “comma”) to the client from a Razor block. When HTML elements are involved, you just write the HTML. When non-html is involved (such as JavaScript, as in this case), this is different. You can’t just write a comma in the middle of a Razor block and expect it to be rendered (this results in a “ CS1525: Invalid expression term ‘,’“).

One solution was specified in Scott Gu’s blog, about using <text> for rendering simple code from Razor blocks. This looks like this:

1:var myArray = [ @for (int i = 1; i <= 10; i++)
2:                 {
3:                     @string.Format("'{0}'", Html.LocalResX("Item" + i.ToString()));
4:                     if (i < 10){
5:                          <text>,</text>
6:                     }
7:                 } ];

Although an acceptable solution, the result seems to be rendered with extraneous newline characters, which was not the desired result. Besides, it did not solve the escaped characters of the string itself. I looked some more and found out that there are other alternatives to do this, such as to use HtmlHelper’s Raw method, which does not encode the characters and simply renders the text “as is”. The result is as follows:

1:var myArray = [ @for (int i = 1; i <= 10; i++)
2:                 {
3:                     @Html.Raw(string.Format("'{0}'", Html.LocalResX("Item" + i.ToString())));
4:                     if (i < 10){
5:                         @Html.Raw(", ");
6:                     }
7:                 } ];

This solved both problems.

Regardless, one thing which I find weird in Razor, is that once you open a Razor code block, you have to familiarize yourself with when you should or shouldn’t specify the @ sign. For example, if I omit the @ prior to Html.Raw (line 3), no compilation error would occur, but the server will render nothing. That is, it’ll completely ignore the entire code statement. On the other hand, if I specify @ prior to the if { … } block (line 4), a compilation error will occur upon render, claiming that: “ Unexpected “if” keyword after “@” character.  Once inside code, you do not need to prefix constructs like “if” with “@”“. Basically, this is understandable at times, but inconsistent: In Scott Gu’s “Introducing Razor” he demonstrates ‘if’ blocks using the @ sign. True, these code blocks are not nested within other Razor code blocks, but this shows the inconsistency.

Leave a comment

Posted by on 13/02/2011 in Software Development


Tags: , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: