Razor View Engine: complex loop and HTML

There are many complex HTML reports in my current project where we do a lot of conditional rendering of TR and TD using rows and colspans.

Sometimes it may look (this is very simplified):

<tr> @foreach (var ourItem in ourList) { if (ourItem != ourList.First()) { <tr> } <td></td> </tr> } 

However, Razor states: "There is no closing"} "character in the foreach loop." (in Visual Studio)

I tried to wrap <tr> in <text></text> , which is why the closing problem closes, only to find it at startup: "Encounted end tag" tr "without the corresponding start tag. Tags are properly balanced."

How would I do such a conditional rendering, convincing Razor not to worry about HTML at all, because HTML is balanced when all the loops are complete. Or at least that was the case when using the ASP.NET View Engine.

+28
asp.net-mvc asp.net-mvc-3 razor
Jan 24 '11 at 12:22
source share
4 answers

Visual Studio Intellisense and syntax highlighting is not one of the best, but in this case it warns you that if the condition is not met, you can get invalid markup, and you should not blame her for that.

It’s important that your project works fine, but you can consider externalizing this logic in HTML helpers, because if you are telling the truth, this is a simplified version of what you have in the views that I don’t even want to imagine what your real code looks like.

IMHO, having so much conditional logic in view, is an abuse. You should definitely consider using HTML helpers or controls such as the MVCContrib Grid .




UPDATE:

You can try the following hack:

 <tr> @foreach (var ourItem in ourList) { if (ourItem != ourList.First()) { @:<tr> } @:<td></td> @:</tr> } 
+35
Jan 24 '11 at 12:26
source share

The razor depends on matching tags to determine automatic transitions between code and markup. You cannot “disable” this Razor function (at least without overwriting large parts of the Razor analyzer).

You can get around this using Darin’s suggestion, although I don’t understand (at least not from your simplified example) why your opinion should be so confusing. Why not write the following code instead:

 @foreach (var ourItem in ourList) { <tr> <td>...</td> </tr> } 

While tags can be balanced in the generated markup, the source you provided makes it very difficult to justify it.

+6
Jan 24 2018-11-11T00:
source share

When trying to use rowspan and trying to get a structure like

 <table> <tr> <td rowspan=2>1:st col</td> <td>2:nd col</td> </tr> <tr> <td>2:nd col</td> </tr> </table> 

You can try:

 @{ var ourList = new List<string> { "1", "2", "3" }; } <table border=1> @foreach(var ourItem in ourList){ <tr> @if (ourItem == ourList.First()) { <td rowspan="@ourList.Count()">@ourItem</td> } <td>@ourItem</td> </tr> } </table> 
+4
Jan 25 '11 at 16:25
source share

I had a similar problem - my solution is Html.Raw ("");

  if (isTrue) { <text><div></text> } ... if(isTrue) { @Html.Raw("</div>"); // <-- closing tag! } 
+4
Feb 04 2018-11-11T00:
source share



All Articles