30

I have a partial view done in razor. When I run it I get the following error - it seems like Razor gets stuck into thinking I'm writing code everywhere.

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

Here is my view:

@model IEnumerable<SomeModel>

<div>
@using(Html.BeginForm("Update", "UserManagement", FormMethod.Post)) {

    @Html.Hidden("UserId", ViewBag.UserId)

@foreach(var link in Model) {
    if(link.Linked) {
         <input type="checkbox" name="userLinks" value="@link.Id" checked="checked" />@link.Description<br />
    } else {
         <input type="checkbox" name="userLinks" value="@link.Id" />@link.Description<br />         
    }
}

}
</div>
BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Jaco Pretorius
  • 24,380
  • 11
  • 62
  • 94

3 Answers3

57

Inside your using block, Razor is expecting C# source, not HTML.

Therefore, you should write foreach without an @.

Inside an HTML tag, Razor expects markup, so you would use @.

For example:

<div>
    <!-- Markup goes here -->
    @if (x) {
        //Code goes here
        if (y) {
            //More code goes here
            <div>
                <!-- Markup goes here -->
                @if (z) { }
            </div>
        }
    }
</div>

You only need an @ if you want to put code where it's expecting markup, or if you want to write output anywhere.

To put non-tag-like markup where it's expecting code, use @: or <text>.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 3
    +1 - I'm finding this to be my #1 stumbling block in learning razor. My brain just doesn't seem to recognize the difference immediately. Getting better at it, but I still find myself writing the wrong thing and then having to think my way through it again. – Joel Etherton Feb 09 '11 at 15:27
  • Yes; this is a subtle but important distinction. I'm planning to write a blog post about this as part of my Dissecting Razor series, but there are still 4 more parts that need to come first. – SLaks Feb 09 '11 at 15:29
  • @Slaks - Yah, the jumping back and forth between code and markup like this just seems wrong to me. It's kind of mind numbing since I've been in a "code or markup but not both" environment for a few years now. Definitely worth the temporary frustration though. I'm drinking the razor koolaid in a big way. – Joel Etherton Feb 09 '11 at 15:35
  • 1
    The VS editor highlighting should help. The subtle blueish tint indicates that you are in code mode. If it's too subtle for you you can change the color by going to VS Options -> Environment -> Fonts and Colors -> Razor Code. – marcind Feb 10 '11 at 01:11
  • 1
    I actuallly did something else to fix this but now I can't figure out what it was. Meh, this is why SO should allow you to answer your own question right away. – Jaco Pretorius Feb 14 '11 at 18:00
  • This was driving me bonkers!! – Chris Marisic Apr 05 '11 at 17:38
3

I just want to add to SLaks answer that markup does not actually disturb the code section only within the markup, and as soon as the closing tag is reached it is reverting back to the markup section.

And similar is once within the markup, you need to use the @ symbol even after code.

Say for example you have the following:

@if(true) {
      <span>
            Markup section here, you need to include the @symbol
            @if(1 = 1)
            {
            }
            @if(2 = 2) @* The @ symbol here is required *@
            {
            }                
      </span>
      @: Code section back here, to output you need the "@:" symbol to display markup, although it is after the markup 
      if(false) @* Here the @ symbol isn't required *@
      {   
            some_statment; @* This will not be sent to the browser *@
            @display_someStament @* If we want to send it to the browser, 
                   then we need the @ symbol even in the code section *@
      }
}
yoel halb
  • 12,188
  • 3
  • 57
  • 52
2

My situation is the opposite of the above, but the logic is the same.

I'm using an iterator on the example razor page and I get the above error if my page starts directly with if and foreach syntax, like below

@if (Model != null)
{
        @foreach (var place in @Model.ToList())
        {
            <div class="swiper-slide">
                <figure class="popular-visits-card">
                    <img src="@place.ImgUrl" alt="">
                    <figcaption class="content">
                        <p class="title">
                            @place.Name
                        </p>
                        <p class="subtitle">
                            @place.Description
                        </p>
                    </figcaption>
                </figure>
            </div>

        }
}

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

if I use an html tag after the if statement, I don't get this error anymore

@model List<Pupularity>
@{
    Layout = null;
}

@if (Model != null)
{
    <div>
        @foreach (var place in @Model.ToList())
        {
            <div class="swiper-slide">
                <figure class="popular-visits-card">
                    <img src="@place.ImgUrl" alt="">
                    <figcaption class="content">
                        <p class="title">
                            @place.Name
                        </p>
                        <p class="subtitle">
                            @place.Description
                        </p>
                    </figcaption>
                </figure>
            </div>

        }
</div>
}
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35