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

我正在尝试在ASP.NET MVC 1项目中使用HTML5数据属性 。 (我是一个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-”。

我的问题:

  • 有什么办法得到这个工作,并使用Html.ActionLink或类似的Html助手HTML5数据属性?
  • 有没有其他的替代机制将自定义数据附加到元素? 这个数据稍后将由JS处理。

更新:MVC 3和更新的版本已经内置了对此的支持。 请参阅下面的JohnnyO高度赞成的答案,了解推荐的解决scheme。

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

 // 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" ) )%> 

只是想法,还没有testing过。

这个问题已经在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的老版本,你可以通过创build这个从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="" /> 

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

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

我看到约翰尼已经提到这一点。

在mvc 4中可以用Underscore(“_”)渲染

剃刀:

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

呈现Html

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

您可以使用新的Html帮助器扩展函数来实现此function,该function将与现有的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" }) %> 

简单:-)

编辑

有点写在这里

我最终使用一个普通的超链接与Url.Action ,如下所示:

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

这是丑陋的,但你有一个更多的控制a标签,有时在AJAX化的网站很有用。

HTH

我不喜欢使用纯粹的“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)); } } 

你可以像这样使用它:

在Mvc:

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

在Html中:

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