319 votes

Comment utiliser HTML 5 de données* les attributs dans ASP.NET MVC

Je suis en train d'utiliser HTML5 attributs data- dans mon ASP.NET MVC 1 projet. (Je suis un C# et ASP.NET MVC débutant.)

 <%= Html.ActionLink("« Previous", "Search",
     new { keyword = Model.Keyword, page = Model.currPage - 1},
     new { @class = "prev", data-details = "Some Details"   })%>

Les données "détails" ci-dessus htmlAttributes donner le message d'erreur suivant:

 CS0746: Invalid anonymous type member declarator. Anonymous type members 
  must be declared with a member assignment, simple name or member access.

Il fonctionne lorsque j'utilise data_details, mais je suppose qu'il faut être en commençant par "données", conformément à la spécification.

Mes questions:

  • Est-il possible de le faire fonctionner et utiliser HTML5 attributs de données avec le langage Html.ActionLink ou similaire Html helpers ?
  • Est-il un autre mécanisme de rechange pour associer des données à un élément? Ces données doivent être traitées ultérieurement par JS.

643voto

Johnny Oshika Points 15580

Ce problème a été abordé dans la ASP.Net MVC 3. Ils sont maintenant convertir automatiquement les caractères de soulignement dans l'attribut html propriétés de tirets. Ils ont eu de la chance sur ce coup, comme le souligne ne sont pas légaux dans les attributs html, donc MVC pouvez en toute confiance implique que vous avez envie d'un tableau de bord lorsque vous utilisez un trait de soulignement.

Par exemple:

@Html.TextBoxFor(vm => vm.City, new { data_bind = "foo" })

rendra ce dans MVC 3:

<input data-bind="foo" id="City" name="City" type="text" value="" />

Si vous utilisez une version plus ancienne de la MVC, vous pouvez imiter ce que MVC 3 est fait par la création de cette méthode statique qui j'ai emprunté de MVC3 du code source:

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;
    }
}

Et puis vous pouvez l'utiliser comme ceci:

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

et cela va rendre les données correctes-* attribut:

<input data-bind="foo" id="City" name="City" type="text" value="" />

115voto

Morten Mertner Points 5786

Mise à jour: MVC 3 et les versions plus récentes ont bâti-support pour cela. Voir JohnnyO très upvoted réponse ci-dessous pour les solutions recommandées.

Je ne pense pas qu'il y a dans l'immédiat, des aides pour y parvenir, mais j'ai deux idées pour vous d'essayer:

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

Juste des idées, n'ai pas testé.

58voto

Oliver Points 2004

C'est même plus facile que tout ce qui est suggéré ci-dessus. Attributs de données dans MVC qui comprennent des tirets (-) sont pris en charge avec l'utilisation de l'underscore (_).

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

Je vois JohnnyO déjà mentionné.

4voto

WestDiscGolf Points 3335

Vous pouvez mettre en œuvre des ce avec un nouveau Html helper extension de fonction qui seront ensuite utilisés de façon similaire à l'existant 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));
}

Et vous appelez ça comme si ...

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

Simples :-)

modifier

peu plus d'une réduction de jusqu' ici

3voto

Keith Williams Points 1126

J'ai fini par utiliser une normale de lien hypertexte avec Url.Action, comme dans:

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

C'est plus laide, mais vous avez un peu plus de contrôle sur l' a balise, ce qui est parfois utile fortement AJAXified sites.

HTH

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X