58

As a test I'm converting a proof-of-concept app we've written from Web Forms to Razor, simply so we can evaluate it.

I've run into one problem so far that's making my head hurt..generating client-side Javascript...

Web-Forms

<script type="text/javascript">
    var jqGridIdList = "<%: Url.Action ("getidlist", "office", new { area = "reports" }) %>";

    var availableIds = [];
    <% for (var i = 0; i < Model.Data.Count (); i++) { %>
    availableIds.push({ value : "<%: Model.Data.ElementAt (i).Text %>", label : "<%: Model.Data.ElementAt (i).Text %>" });
    <% } %>
</script>

Razor Syntax

<script type="text/javascript">
    var jqGridIdList = "@Url.Action("getidlist", "office", new { area = "reports" })";

    var availableIds = [];
    @for(var i = 0; i < Model.Data.Count (); i++) {
    availableIds.push({ value : "@Model.Data.ElementAt(i).Text", label : "@Model.Data.ElementAt(i).Text" });
    }
</script>

The compiler gives me the following error on the 'availableIds.push' line:

Compiler Error Message: CS1525: Invalid expression term '{'

It's obviously trying to compile it as C#...but how do I stop it?

Thanks,
Kieron

Kieron
  • 26,748
  • 16
  • 78
  • 122

1 Answers1

106

You need to wrap it in the pseudo element <text>. This will switch the parser back to html mode and it will then parse the javascript as part of the html and not c#. The reason it happens is the @for() is a c# block and anything treated within is also considered c# until it's escaped by an html tag. Since you probably don't want an html tag razor provides the <text> tag to switch modes.

If you notice the difference in your asp.net webforms you end the <% for line with a %> which takes it out of c# mode. If you download the razor highlighter extension for visual studio 2010 it will help you see when code is treated as code and html is treated as html.

<script type="text/javascript">
    var jqGridIdList = "@Url.Action("getidlist", "office", new { area = "reports" })";

    var availableIds = [];
    @for(var i = 0; i < Model.Data.Count (); i++) {
        <text>availableIds.push({ value : "@Model.Data.ElementAt(i).Text", label : "@Model.Data.ElementAt(i).Text" });</text>
    }
</script>

Update for latest version

You can now use the @: syntax for even more readability

<script type="text/javascript">
    var jqGridIdList = "@Url.Action("getidlist", "office", new { area = "reports" })";

    var availableIds = [];
    @for(var i = 0; i < Model.Data.Count (); i++) {
        @:availableIds.push({ value : "@Model.Data.ElementAt(i).Text", label : "@Model.Data.ElementAt(i).Text" });
    }
</script>
Buildstarted
  • 26,529
  • 10
  • 84
  • 95
  • Excellent, thanks - I'll try that when I'm back in the office. Where are those extensions...are they in the gallery? – Kieron Oct 28 '10 at 22:39
  • 1
    Yeah, just search for "Razor" on the visual studio gallery or you can go http://visualstudiogallery.msdn.microsoft.com/en-us/8dc77b9c-7c83-4392-9c46-fd15f3927a2e?SRC=Home – Buildstarted Oct 28 '10 at 22:58
  • 1
    if it's just a single line of content that needs to be parsed you can use Razor's '@:' prefix e.g. @:availableIds.push(...) – Matt Cotton Sep 28 '11 at 09:21
  • Can you please tell the basic advantages of wrapping the code in `` ? In case of **Js/Html/server** code. – Imad Alazani Jul 05 '13 at 04:57
  • `` only tells the razor parser that this should be output to the browser. Otherwise the parser would assume it's code. because it isn't an html element. – Buildstarted Jul 07 '13 at 06:19