I have a situation where I need to write an HTML Helper to extend another html helper. Normally, the helper would look like this.
@Html.TextAreaFor(model => model.Content, new { @class = "some css", @data_bind = "some other stuff..." })
This works fine, but it has to be wrapped in some other HTML that is always the same. I wanted to encapsulate it for convenience, like this.
public static MvcHtmlString CondensedHelperFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
var stringBuilder = new System.Text.StringBuilder();
var tag = new TagBuilder("div"); tag.AddCssClass("some_css");
stringBuilder.Append(toolbar.ToString(TagRenderMode.SelfClosing));
stringBuilder.Append(htmlHelper.TextAreaFor(expression, htmlAttributes));
// more tags and such...
return new MvcHtmlString(stringBuilder.ToString());
}
The line stringBuilder.Append(htmlHelper.TextAreaFor... is what I want to change. The CSS class that has to go there is always going to be present. So I would rather include it here. However I would like to be able to specify additional CSS classes in the top-level helper. So …
@Html.CondensedHelperFor(model => model.Content, new { @class = "some_other_css" })
And the static css that will always be there get blanketed in through the Helper.
Any ideas?
First, create a method (the best would be to create an extension method) that converts an object to IDictionary via type reflection:
Now, make use of C# 4.0 ExpandoObject, which allows adding properties at runtime.
You would end up with something like this: