首页 文章

如何在ASP.NET MVC中的HTML-5 data- *属性中使用破折号

提问于
浏览
304

我试图在我的ASP.NET MVC 1项目中使用HTML5 data- attributes . (我是C#和ASP.NET MVC的新手 . )

<%= Html.ActionLink("« Previous", "Search",
     new { keyword = Model.Keyword, page = Model.currPage - 1},
     new { @class = "prev", data-details = "Some Details"   })%>

上面的htmlAttributes中的“data-details”给出以下错误:

CS0746: Invalid anonymous type member declarator. Anonymous type members 
  must be declared with a member assignment, simple name or member access.

它在我使用data_details时有效,但我想它需要按照规范以“data-”开头 .

我的问题:

  • 有没有办法让这个工作并使用HTML5数据属性与Html.ActionLink或类似的Html助手?

  • 是否有其他替代机制将自定义数据附加到元素?此数据稍后将由JS处理 .

8 回答

  • -3

    它比上面提到的一切都更容易 . MVC中包含破折号( - )的数据属性通过使用下划线(_)来满足 .

    <%= Html.ActionLink("« Previous", "Search",
     new { keyword = Model.Keyword, page = Model.currPage - 1},
     new { @class = "prev", data_details = "Some Details"   })%>
    

    我看到JohnnyO已经提到了这一点 .

  • 58

    Update: MVC 3 and newer versions have built-in support for this. See JohnnyO's highly upvoted answer below for recommended solutions.

    我不认为有任何直接的帮助来实现这一点,但我有两个想法让你尝试:

    // 1: pass dictionary instead of anonymous object
    <%= Html.ActionLink( "back", "Search",
        new { keyword = Model.Keyword, page = Model.currPage - 1},
        new Dictionary<string,Object> { {"class","prev"}, {"data-details","yada"} } )%>
    
    // 2: pass custom type decorated with descriptor attributes
    public class CustomArgs
    {
        public CustomArgs( string className, string dataDetails ) { ... }
    
        [DisplayName("class")]
        public string Class { get; set; }
        [DisplayName("data-details")]
        public string DataDetails { get; set; }
    }
    
    <%= Html.ActionLink( "back", "Search",
        new { keyword = Model.Keyword, page = Model.currPage - 1},
        new CustomArgs( "prev", "yada" ) )%>
    

    只是想法,没有测试过 .

  • 0

    这个问题已在ASP.Net MVC 3中得到解决 . 它们现在自动将html属性属性中的下划线转换为破折号 . 他们在这个问题上很幸运,因为下划线在html属性中是不合法的,所以当你使用下划线时,MVC可以自信地暗示你喜欢破折号 .

    例如:

    @Html.TextBoxFor(vm => vm.City, new { data_bind = "foo" })
    

    将在MVC 3中呈现:

    <input data-bind="foo" id="City" name="City" type="text" value="" />
    

    如果你还在使用旧版本的MVC,你可以通过创建我从MVC3的源代码中借用的静态方法来模仿MVC 3正在做的事情:

    public class Foo {
        public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes) {
            RouteValueDictionary result = new RouteValueDictionary();
            if (htmlAttributes != null) {
                foreach (System.ComponentModel.PropertyDescriptor property in System.ComponentModel.TypeDescriptor.GetProperties(htmlAttributes)) {
                    result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
                }
            }
            return result;
        }
    }
    

    然后你可以像这样使用它:

    <%: Html.TextBoxFor(vm => vm.City, Foo.AnonymousObjectToHtmlAttributes(new { data_bind = "foo" })) %>
    

    这将呈现正确的data- *属性:

    <input data-bind="foo" id="City" name="City" type="text" value="" />
    
  • 613

    在mvc 4中可以使用下划线(“_”)渲染

    Razor:

    @Html.ActionLink("Vote", "#", new { id = item.FileId, }, new { @class = "votes", data_fid = item.FileId, data_jid = item.JudgeID, })
    

    Rendered Html

    <a class="votes" data-fid="18587" data-jid="9" href="/Home/%23/18587">Vote</a>
    
  • 17

    您可以使用新的Html辅助扩展函数来实现它,然后它将与现有的ActionLink类似地使用 .

    public static MvcHtmlString ActionLinkHtml5Data(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, object htmlDataAttributes)
    {
        if (string.IsNullOrEmpty(linkText))
        {
            throw new ArgumentException(string.Empty, "linkText");
        }
    
        var html = new RouteValueDictionary(htmlAttributes);
        var data = new RouteValueDictionary(htmlDataAttributes);
    
        foreach (var attributes in data)
        {
            html.Add(string.Format("data-{0}", attributes.Key), attributes.Value);
        }
    
        return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null, actionName, controllerName, new RouteValueDictionary(routeValues), html));
    }
    

    你这么称呼它......

    <%: Html.ActionLinkHtml5Data("link display", "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = "some extra info" })  %>
    

    简单:-)

    edit

    更多的写作here

  • 109

    我最终使用了正常的超链接和 Url.Action ,如下所示:

    <a href='<%= Url.Action("Show", new { controller = "Browse", id = node.Id }) %>'
      data-nodeId='<%= node.Id %>'>
      <%: node.Name %>
    </a>
    

    它_1134024_对 a 标签有了更多的控制权,这在大量的AJAXified网站中有时很有用 .

    HTH

  • 4

    我不喜欢使用纯粹的“a”标签,打字过多 . 所以我来解决方案 . 看起来它看起来

    <%: Html.ActionLink(node.Name, "Show", "Browse", 
                        Dic.Route("id", node.Id), Dic.New("data-nodeId", node.Id)) %>
    

    Dic类的实现

    public static class Dic
    {
        public static Dictionary<string, object> New(params object[] attrs)
        {
            var res = new Dictionary<string, object>();
            for (var i = 0; i < attrs.Length; i = i + 2)
                res.Add(attrs[i].ToString(), attrs[i + 1]);
            return res;
        }
    
        public static RouteValueDictionary Route(params object[] attrs)
        {
            return new RouteValueDictionary(Dic.New(attrs));
        }
    }
    
  • 3

    你可以像这样使用它:

    In Mvc:

    @Html.TextBoxFor(x=>x.Id,new{@data_val_number="10"});
    

    In Html:

    <input type="text" name="Id" data_val_number="10"/>
    

相关问题