我试图使用HTML5的数据属性在我的ASP。NET MVC 1项目。(我是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处理。


当前回答

这个问题已经在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所做的,这个静态方法是我从MVC3的源代码中借来的:

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="" />

其他回答

这个问题已经在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所做的,这个静态方法是我从MVC3的源代码中借来的:

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="" />

你可以用一个新的Html助手扩展函数来实现这个功能,它将被类似于现有的ActionLinks。

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

这里写得更多

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

我最终使用了一个普通的超链接和Url。动作,如:

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

它更丑陋,但您可以对a标记有更多的控制,这在重度ajax化的站点中有时很有用。

HTH

在mvc 4中可以用下划线(“_”)呈现

剃须刀:

@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>