ASP.NET MVC Helpers,将两个对象htmlAttributes合并在一起

Cie*_*iel 30 .net c# asp.net-mvc-3

我有一种情况需要编写一个HTML Helper来扩展另一个html帮助器.通常,帮助器看起来像这样.

@Html.TextAreaFor(model => model.Content, new { @class = "some css", @data_bind = "some other stuff..." })

这样可以正常工作,但它必须包含在其他一些始终相同的HTML中.为了方便,我想封装它,就像这样.

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());
        }
Run Code Online (Sandbox Code Playgroud)

这条线stringBuilder.Append(htmlHelper.TextAreaFor...是我想要改变的.必须去那里的CSS类总会出现.所以我宁愿把它包括在这里.但是,我希望能够在顶级助手中指定其他CSS类.所以......

@Html.CondensedHelperFor(model => model.Content, new { @class = "some_other_css" })

永远存在的静态css会通过Helper覆盖.

有任何想法吗?

Noa*_*oam 50

您可以使用标准MVC帮助程序方法执行此操作.

HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)
Run Code Online (Sandbox Code Playgroud)

htmlAttributes 是一个对象

  • 那更简单! (3认同)

Pio*_*myd 22

首先,创建一个方法(最好的方法是创建一个扩展方法),通过类型反射将对象转换为IDictionary:

public static IDictionary<string, object> ToDictionary(this object data) 
{
        if(data == null) return null; // Or throw an ArgumentNullException if you want

        BindingFlags publicAttributes = BindingFlags.Public | BindingFlags.Instance;
        Dictionary<string, object> dictionary = new Dictionary<string, object>();

        foreach (PropertyInfo property in 
                 data.GetType().GetProperties(publicAttributes)) { 
            if (property.CanRead) {
                dictionary.Add(property.Name, property.GetValue(data, null));
            }
        }
        return dictionary;
}
Run Code Online (Sandbox Code Playgroud)

现在,使用C#4.0 ExpandoObject,它允许在运行时添加属性.你会得到这样的东西:

public static MvcHtmlString CondensedHelperFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
{
    var dictAttributes = htmlAttributes.ToDictionary();

    var result = new ExpandoObject();
    var d = result as IDictionary<string, object>; //work with the Expando as a Dictionary

    if(dictAttributes != null)
    {
        foreach (var pair in dictAttributes)
        {
            d[pair.Key] = pair.Value;
        }
    }

    // Add other properties to the dictionary d here
    // ...

    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, result));

    return new MvcHtmlString(stringBuilder.ToString());
}
Run Code Online (Sandbox Code Playgroud)