337

ASP.NET MVC 1 プロジェクトでHTML5 data- 属性を使用しようとしています。(私は 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 によって処理されます。
4

8 に答える 8

663

この問題は、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 のソース コードから借用した次の静的メソッドを作成することで、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="" />
于 2010-12-23T01:08:26.840 に答える
118

更新: MVC 3 以降のバージョンには、これに対するサポートが組み込まれています。推奨される解決策については、以下の JohnnyO の非常に支持された回答を参照してください。

これを達成するためのすぐに役立つ方法はないと思いますが、試していただきたい 2 つのアイデアがあります。

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

単なるアイデアであり、テストしていません。

于 2010-03-26T01:27:44.980 に答える
4

You can implement this with a new Html helper extension function which will then be used similarly to the existing 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));
}

And you call it like so ...

<%: Html.ActionLinkHtml5Data("link display", "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = "some extra info" })  %>

Simples :-)

edit

bit more of a write up here

于 2011-01-12T21:06:00.153 に答える
3

次のように、通常のハイパーリンクを とともに使用することになりUrl.Actionました。

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

これは醜いですが、aタグをより細かく制御できます。これは、AJAX 化されたサイトで役立つ場合があります。

HTH

于 2010-07-15T18:46:11.553 に答える
0

私は純粋な "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));
    }
}
于 2010-12-11T12:49:36.327 に答える
-2

次のように使用できます。

Mvc で:

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

Html で:

<input type="text" name="Id" data_val_number="10"/>
于 2016-01-08T07:07:24.300 に答える