I'm developing an application in asp mvc, and I want to create some friendly controls for developers, like Server controls in asp.net WebForms . In this case, I want to create a bootstrap panel that has some fixed html and render inside a template of items. I am doing it this way:
public static MvcHtmlString BootPanel<T>(this IEnumerable<T> items, Func<T, HelperResult> template, string title = "")
{
StringBuilder sb = new StringBuilder();
sb.Append("<div class='panel panel-info'>");
sb.Append("<div class='panel-heading'>");
sb.Append(title);
sb.Append("</div>");
sb.Append("<div class='panel-body'>");
var hr = new HelperResult(writer =>
{
foreach (var item in items)
{
template(item).WriteTo(writer);
}
});
sb.Append(hr.ToHtmlString());
sb.Append("</div>");
sb.Append("</div>");
return MvcHtmlString.Create(sb.ToString());
}
This is the razor View:
@{
var videoGames = new[] {
new VideoGame {nombre = "Shadows of mordor", precio = 66},
new VideoGame {nombre = "Spiderman", precio = 50}
};
}
@videoGames.BootPanel(@<div>
@item.nombre @item.precio
</div>
, "Titulo")
The output is rendered correctly using the bootstrap classes:
The question is. Is this a correct way of implementing this kind of control?
EDIT:
Following your answers I updated the helper yo use TagBuilder:
public static MvcHtmlString BootPanel<T>(this IEnumerable<T> items, Func<T, HelperResult> template, string title = "")
{
TagBuilder PanelDiv = new TagBuilder("div");
PanelDiv.AddCssClass("panel panel-info");
TagBuilder PanelHeading = new TagBuilder("div");
PanelHeading.AddCssClass("panel-heading");
PanelHeading.SetInnerText(title);
TagBuilder PanelBody = new TagBuilder("div");
PanelBody.AddCssClass("panel-body");
var hr = new HelperResult(writer =>
{
foreach (var item in items)
{
template(item).WriteTo(writer);
}
});
PanelBody.InnerHtml = hr.ToHtmlString();
PanelDiv.InnerHtml = PanelHeading.ToString() +
PanelBody.ToString();
return MvcHtmlString.Create(PanelDiv.ToString());
}