【问题标题】:Use an Anonymous object in HtmlHelper extension method在 HtmlHelper 扩展方法中使用匿名对象
【发布时间】:2014-04-23 15:21:35
【问题描述】:

我想扩展HtmlHelper,以便使用自定义属性(例如'async')呈现脚本标签

我想这样使用它

@Html.RenderBundleScript("/mybundleName", new { async = ""})

这是我的代码,它不起作用(特别是,attributes.ToString() 给出:System.Web.Routing.RouteValueDictionary 而不是 asyncasync=''):

public static IHtmlString RenderBundleScript(this HtmlHelper htmlHelper, 
                               string bundlePath, object htmlAttributes)
{
    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    string attributesValue = (attributes == null) ? 
                             string.Empty : attributes.ToString();
    if (string.IsNullOrEmpty(attributesValue))
    {
        return Scripts.Render(bundlePath);
    }
    else
    {
        //var tag = new TagBuilder("script");
        // tag.MergeAttribute() ???
        return Scripts.RenderFormat("<script src='{0}' " + 
                       attributesValue + 
                       " type='text/javascript'></script>", bundlePath);
    }
}

【问题讨论】:

  • 也许您可以更好地定义“不起作用”?你有任何输出或异常吗?如果有,是什么?
  • 我不会来将匿名对象 {async=""} 转换为 html 属性列表 ("async=''")。

标签: c# .net asp.net-mvc html-helper anonymous-class


【解决方案1】:

scripts 类有一个方法Scripts.RenderFormat,它接受一个格式字符串,用于渲染包中的每个脚本。

这对于您的扩展方法可能会派上用场。您可以使用 html 属性为脚本标签创建格式字符串。此格式字符串如下所示:

 <script async="" fooAttrib="1" src="{0}" type="text/javascript"></script>

所以你可以通过实现这个想法来更新扩展方法:

public static IHtmlString RenderBundleScript(this HtmlHelper htmlHelper,
                        string bundlePath, object htmlAttributes)
{
    if (htmlAttributes == null)
    {
        return Scripts.Render(bundlePath);
    }
    else
    {            
        //Create format string for the script tags, including additional html attributes    
        TagBuilder tag = new TagBuilder("script");
        tag.Attributes.Add("src", "{0}");
        tag.Attributes.Add("type", "text/javascript");
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        foreach (var key in attributes.Keys)
        {
            tag.Attributes.Add(key, attributes[key].ToString());
        }                
        var tagFormat = tag.ToString(TagRenderMode.Normal);

        //render the scripts in the bundle using the custom format
        return Scripts.RenderFormat(tagFormat, bundlePath);
    }
}

如果你在下面的行中调用它:

@Html.RenderBundleScript("~/bundles/jqueryval", new {async = "", dummy="1"})

它将呈现此输出:

<script async="" dummy="1" src="/Scripts/jquery.validate.js" type="text/javascript"></script>
<script async="" dummy="1" src="/Scripts/jquery.validate.unobtrusive.js" type="text/javascript"></script>

希望对你有帮助!

【讨论】:

  • 这项工作很好......唯一的问题是没有(?)添加无价值属性的可能性,比如“异步”......
  • 好点!但是,根据 W3C html5 spec,空值(或等于属性名称的值,如 async="async")将是有效的:如果属性存在,其值必须是空字符串或是属性的规范名称的不区分大小写的匹配,没有前导或尾随空格。如果您仍然需要,您可能需要手动构建 tagFormat 字符串,而不是使用 TagBuilder 类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多