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

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 Url.Action, as in:

1
2
3
'
  data-nodeId='<%= node.Id %>'>
  <%: node.Name %>

更糟糕的是,你对a标签有了更多的控制,它有时在半封闭的网站中很有用。

高温高压


我不喜欢使用纯粹的"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"/>