How to use dashes in HTML-5 data-* attributes in ASP.NET MVC
我正在尝试在我的ASP.NET MVC 1项目中使用HTML5数据属性。(我是C和ASP.NET MVC新手。)
1 2 3 | <%= Html.ActionLink("? Previous","Search", new { keyword = Model.Keyword, page = Model.currPage - 1}, new { @class ="prev", data-details ="Some Details" })%> |
上述htmlattributes中的"data details"给出以下错误:
1 2 | CS0746: Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access. |
当我使用数据细节时,它是有效的,但是我想它需要从"数据"开始,根据规范。
我的问题:
- 是否有任何方法可以使其正常工作,并将html5数据属性与html.actionlink或类似的html助手一起使用?
- 是否有其他替代机制可以将自定义数据附加到元素?这些数据稍后将由JS处理。
这个问题已经在ASP.NET MVC 3中解决。现在,它们自动将HTML属性属性属性中的下划线转换为短划线。他们在这一点上很幸运,因为下划线在HTML属性中是不合法的,所以MVC可以自信地暗示您在使用下划线时希望使用破折号。
例如:
1 | @Html.TextBoxFor(vm => vm.City, new { data_bind ="foo" }) |
将在MVC 3中呈现:
1 | <input data-bind="foo" id="City" name="City" type="text" value="" /> |
如果您仍在使用较旧版本的MVC,则可以通过创建我从MVC3源代码中借用的静态方法来模拟MVC 3正在执行的操作:
1 2 3 4 5 6 7 8 9 10 11 | 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; } } |
然后你可以这样使用它:
1 | <%: Html.TextBoxFor(vm => vm.City, Foo.AnonymousObjectToHtmlAttributes(new { data_bind ="foo" })) %> |
这将呈现正确的数据-*属性:
1 | <input data-bind="foo" id="City" name="City" type="text" value="" /> |
更新:MVC 3和更新版本对此有内置支持。有关推荐的解决方案,请参阅下面的约翰尼奥的高投票率答案。
我不认为有任何直接的帮助来实现这一点,但我有两个想法供您尝试:
1 2 3 4 5 6 7 | // 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 <div class="suo-content">[collapse title=""]<ul><li>你好。如果要使用第一种方法,只需确保字典的类型为dictionary<string,object>。</li><li>虽然这在技术上可行,但推荐的方法(从MVC 3开始)是使用下划线代替连字符(如Johnnyo指出的)。</li><li>把整个世界和这个选择的答案混淆,直到注意到上面的真实答案!</li></ul>[/collapse]</div><p><center>[wp_ad_camp_1]</center></p><hr><P>比上面的建议更简单。MVC中包含破折号(-)的数据属性可通过使用下划线(uu)来满足。</P>[cc]<%= Html.ActionLink("? Previous","Search", new { keyword = Model.Keyword, page = Model.currPage - 1}, new { @class ="prev", data_details ="Some Details" })%> |
我知道约翰尼奥已经提到了这个。
在MVC中,4可以用下划线("uu")呈现。
Razor:
1 | @Html.ActionLink("Vote","#", new { id = item.FileId, }, new { @class ="votes", data_fid = item.FileId, data_jid = item.JudgeID, }) |
渲染HTML
1 | Vote |
您可以使用一个新的HTML助手扩展函数来实现这一点,该函数随后将类似于现有的actionLinks。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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)); } |
你这样称呼它…
1 | <%: Html.ActionLinkHtml5Data("link display","Action","Controller", new { id = Model.Id }, new { @class="link" }, new { extra ="some extra info" }) %> |
简单:
编辑
这里写得再多一点
I ended up using a normal hyperlink along with
1 2 3 | ' data-nodeId='<%= node.Id %>'> <%: node.Name %> |
更糟糕的是,你对
高温高压
我不喜欢使用纯粹的"A"标签,太多的打字。所以我带着解决方案来。从外观看
1 2 | <%: Html.ActionLink(node.Name,"Show","Browse", Dic.Route("id", node.Id), Dic.New("data-nodeId", node.Id)) %> |
dic类的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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中:
1 | @Html.TextBoxFor(x=>x.Id,new{@data_val_number="10"}); |
在HTML中:
1 | <input type="text" name="Id" data_val_number="10"/> |