I've got a view that iterates a collection and calls DisplayFor()
for each element in the collection.
I need to manually iterate (as opposed to passing the collection to DisplayFor) in order to tell the template if a break in the list should be drawn. The items in the list will only be of 2 types, ordered by them, so I only need to show this break once.
My template is found and called correctly.
I can see the HTML it generates correctly, ie: DisplayFor().ToHtmlString()
I can set this HTML as a scoped variable, ie: var html = DisplayFor().ToHtmlString()
..
But even Html.Raw(html)
does not render it in the browser - the HTML has simply vanished.
What's going on?
var renderBreakInList = Model.Items.Any(x => x.IsSomeType);
foreach(var item in Model.Items)
{
var renderBreak = renderBreakInList && item.IsOtherType;
Html.DisplayFor(x => item, new { renderBreak = renderBreak });
if (renderBreak)
{
renderBreakInList = false;
}
}
The Html.DisplayFor
method in itself does not render anything to the response just returns the generated HTML as a MvcHtmlString
.
In order to actually write the rendered HTML to the response you need to tell this to Razor with using the @
sign:
@Html.DisplayFor(x => item, new { renderBreak = renderBreak })
So your whole code should look like this:
@{
var renderBreakInList = Model.Items.Any(x => x.IsSomeType);
foreach(var item in Model.Items)
{
var renderBreak = renderBreakInList && item.IsOtherType;
@Html.DisplayFor(x => item, new { renderBreak = renderBreak })
if (renderBreak)
{
renderBreakInList = false;
}
}
}
Or you can use the WebPageBase.Write
method (which gets called under the hood when using the @
sign):
Write(Html.DisplayFor(x => item, new { renderBreak = renderBreak }));