Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Razor Won't Accept My Valid Markup

I like the Razor syntax a lot, but it certainly falls short of perfect. For example, I have the following block of markup.

@if (Model.FeaturedDestinations != null && Model.FeaturedDestinations.Count() > 0)
{
    int column = 0;

    foreach (var d in Model.FeaturedDestinations)
    {
        column++;
        if (column > 4)
        {
            </div>
            @{ column = 1; }
        }
        if (column == 1)
        {
            @:<div class="row-fluid">
        }
        <div class="span3">
            @RenderDestination(d)
        </div>
    }
    </div>
}

So, the editor gives me the squiggly lines indicating that I have an ending <div> tag before an opening one. I can live with that. But when I run the app, I actually get the following run-time error:

Encountered end tag "div" with no matching start tag. Are your start/end tags properly balanced?

Obviously, I cannot live with that! So is there any trick for dealing with this case? I know what I'm doing as far as the markup I want. But Razor doesn't think so and it's taking over.

And why the heck is MVC wasting cycles checking for balanced tags?

like image 382
Jonathan Wood Avatar asked May 15 '12 23:05

Jonathan Wood


People also ask

Does ASP.NET MVC use Razor pages?

A Razor Page is almost the same as ASP.NET MVC's view component. It has basically the syntax and functionality same as MVC. The basic difference between Razor pages and MVC is that the model and controller code is also added within the Razor Page itself. You do not need to add code separately.

How can you comment using Razor syntax?

Razor uses the syntax "@* .. *@" for the comment block but in a C# code block we can also use "/* */" or "//". HTML comments are the same, "<!

Is Razor a markup language?

Razor is a markup syntax that lets you embed server-based code (Visual Basic and C#) into web pages. Server-based code can create dynamic web content on the fly, while a web page is written to the browser.


2 Answers

For reasons I don't understand, the following corrected the issue:

@if (Model.FeaturedDestinations != null && Model.FeaturedDestinations.Count() > 0)
{
    int column = 0;

    foreach (var d in Model.FeaturedDestinations)
    {
        column++;

        if (column > 4)
        {
            @:</div>
            column = 1;
        }

        if (column == 1)
        {
            @:<div class="row-fluid">
        }
        <div class="span3">
            @RenderDestination(d)
        </div>
    }
    @:</div>
}

Note the addition of @: before several tags. I don't know why these are necessary--the Razor highlighting indicated that it recognized these were tags and not code.

Also, why did this make the error go away? The thing that caused the run-time error has not changed. Perhaps someone can fill in the blanks for me.

like image 179
Jonathan Wood Avatar answered Sep 19 '22 07:09

Jonathan Wood


You need to add @: in front of the tag (as identified in the marked answer). This blog entry explains the reason for that:

http://weblogs.asp.net/scottgu/archive/2010/12/15/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax.aspx

From the blog:

One of the techniques that Razor uses to implicitly identify when a code block ends is to look for tag/element content to denote the beginning of a content region.

and

Not all content container blocks start with a tag element tag, though, and there are scenarios where the Razor parser can’t implicitly detect a content block.

Razor addresses this by enabling you to explicitly indicate the beginning of a line of content by using the @: character sequence within a code block. The @: sequence indicates that the line of content that follows should be treated as a content block:

like image 24
Edyn Avatar answered Sep 19 '22 07:09

Edyn