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

Sha*_*eem 318 asp.net-mvc html5 custom-data-attribute

我试图在我的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"   })%>
Run Code Online (Sandbox Code Playgroud)

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

 CS0746: Invalid anonymous type member declarator. Anonymous type members 
  must be declared with a member assignment, simple name or member access.
Run Code Online (Sandbox Code Playgroud)

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

我的问题:

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

Joh*_*ika 641

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

例如:

@Html.TextBoxFor(vm => vm.City, new { data_bind = "foo" })
Run Code Online (Sandbox Code Playgroud)

将在MVC 3中呈现:

<input data-bind="foo" id="City" name="City" type="text" value="" />
Run Code Online (Sandbox Code Playgroud)

如果你还在使用旧版本的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

<input data-bind="foo" id="City" name="City" type="text" value="" />
Run Code Online (Sandbox Code Playgroud)

  • +++ 1,这应该是现在标记为正确的答案 (19认同)
  • 由于某些原因,这对我不起作用.查看源显示data_*.使用MVC3.有任何想法吗? (6认同)
  • @RubensMariuzzo这不是在`RouteValueDictionary`中,而是在MVC3的`Html.Something()`方法中."WebGrid"可能没有以相同的方式升级,或者您可以检查`System.Web.Helpers.dll上的版本 (2认同)

Mor*_*ner 115

更新:MVC 3和更新版本内置了对此的支持.有关推荐的解决方案,请参阅下面的JohnnyO高度评价的答案.

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

// 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" ) )%>
Run Code Online (Sandbox Code Playgroud)

只是想法,没有测试过.

  • 虽然这在技术上有效,但推荐的方法(从MVC 3开始)是使用下划线代替连字符(正如JohnnyO指出的那样). (40认同)
  • 你好.如果要使用第一种方法,只需确保字典的类型为Dictionary <String,Object>. (5认同)
  • 用这个选择的答案混淆整个世界*直到*注意到上面的真实答案! (3认同)

Oli*_*ver 58

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

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

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

  • 负责这个的方法是:HtmlHelper.AnonymousObjectToHtmlAttributes(object),以防有人想知道为什么他们的自定义扩展不会用连字符替换下划线. (12认同)

mzo*_*erz 18

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

剃刀:

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

呈现的Html

<a class="votes" data-fid="18587" data-jid="9" href="/Home/%23/18587">Vote</a>
Run Code Online (Sandbox Code Playgroud)