I know I can add html attributes to my tag by doing something like:
var htmlAttributes = new RouteValueDictionary { { "data-foo", "bar" } };
var tag = new TagBuilder("div");
tag.MergeAttributes(htmlAttributes );
@tag
Output:
<div data-foo="bar"></div>
I wonder if I can add attributes in a similar way by using markup instead of a tag builder. Maybe something like:
var htmlAttributes = new RouteValueDictionary { { "data-foo", "bar" } };
<div @htmlAttributes.ToHtmlAttributes() ></div>
Expected output:
<div data-foo="bar"></div>
Clearly, I wouldn't be able to handle merge conflicts this way. However, I think it's worth it because the second way is so much more readable.
You can write your own extension method:
namespace SomeNamespace
{
public static class RouteValueDictionaryExtensions
{
public static IHtmlString ToHtmlAttributes(this RouteValueDictionary dictionary)
{
var sb = new StringBuilder();
foreach (var kvp in dictionary)
{
sb.Append(string.Format("{0}=\"{1}\" ", kvp.Key, kvp.Value));
}
return new HtmlString(sb.ToString());
}
}
}
which will be used exactly how you've described:
@using SomeNamespace
@{
var htmlAttributes = new RouteValueDictionary
{
{"data-foo", "bar"},
{"data-bar", "foo"}
};
}
<div @htmlAttributes.ToHtmlAttributes()> </div>
the result is:
<div data-foo="bar" data-bar="foo" > </div>
Edit:
If you want to use TagBuilder
, you can alternatively write another extension which uses it internally:
public static IHtmlString Tag(this HtmlHelper helper,
RouteValueDictionary dictionary,
string tagName)
{
var tag = new TagBuilder(tagName);
tag.MergeAttributes(dictionary);
return new HtmlString(tag.ToString());
}
and the usage shown below below gives the same output html as previously:
@Html.Tag(htmlAttributes, "div")