2010-03-26 3 views
302

J'essaie d'utiliser HTML5 data- attributes dans mon projet ASP.NET MVC 1. (Je suis un C# et ASP.NET MVC débutant.)Comment utiliser des tirets dans les attributs de données HTML * 5 dans ASP.NET MVC

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

Les "données-détails" dans les htmlAttributes ci-dessus l'erreur suivante:

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

Il fonctionne quand j'utilise data_details, mais Je suppose qu'il faut commencer par "data-" selon les spécifications.

Mes questions:

  • Est-il possible d'obtenir ce travail et utiliser des données HTML5 attributs avec Html.ActionLink ou aides Html semblables?
  • Existe-t-il un autre mécanisme permettant d'associer des données personnalisées à un élément? Ces données doivent être traitées ultérieurement par JS.
+4

c'est une vieille question avec la réponse pas à jour - utilisateurs de MVC 3 et devrait voir ci-dessus cette question http://stackoverflow.com/questions/2897733/hyphenated-html-attributs-avec-asp-net-mvc –

Répondre

105

Mise à jour: MVC 3 et les versions plus récentes prennent en charge cette fonctionnalité. Voir la réponse fortement mise de JohnnyO ci-dessous pour les solutions recommandées.

Je ne pense pas qu'il y ait des aides immédiates 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"))%> 

seulement des idées, ne l'ont pas testé.

+5

Salut. Si vous voulez utiliser la 1ère approche, assurez-vous que votre dictionnaire est de type Dictionary . –

+39

Bien que cela fonctionne techniquement, la façon recommandée (à partir de MVC 3) est d'utiliser un trait de soulignement à la place du trait d'union (comme JohnnyO l'a souligné). –

+3

Confondre le monde entier avec cette réponse * choisie * jusqu'à * remarquer la vraie réponse ci-dessus! –

3

j'ai fini à l'aide d'un lien hypertexte normale avec Url.Action, comme dans:

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

Il est plus laid, mais vous avez un peu plus de contrôle sur l'étiquette a, ce qui est parfois utile dans les sites fortement AJAXified .

HTH

0

Je n'aime pas utiliser pure "une" étiquette, trop taper. Donc, je viens avec une solution. Vu paraître

<%: Html.ActionLink(node.Name, "Show", "Browse", 
        Dic.Route("id", node.Id), Dic.New("data-nodeId", node.Id)) %> 

La mise en œuvre de la classe 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)); 
    } 
} 
+1

Sûrement il y a un meilleur nom de classe ... un "t" supplémentaire à la fin au moins! – hvaughan3

601

Ce problème a été abordé dans ASP.Net MVC 3. Ils maintenant convertir automatiquement en underscores propriétés attribut html à tirets. Ils ont eu de la chance sur celui-ci, car les underscores ne sont pas légaux dans les attributs html, donc MVC peut impliquer avec confiance que vous aimeriez un tiret lorsque vous utilisez un trait de soulignement.

Par exemple:

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

rendra ceci dans MVC 3:

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

Si vous utilisez encore une ancienne version de MVC, vous pouvez imiter ce que MVC 3 fait en créant cette méthode statique que j'ai emprunté à partir du code source de 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; 
    } 
} 

Et puis vous pouvez l'utiliser comme ceci:

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

et cela va rendre le Data- correct * attribut:

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

Cela ne fonctionne pas pour moi pour une raison quelconque. Voir la source montre data_ *. En utilisant MVC3. Des idées? –

+0

Bonjour Simon, avez-vous résolu votre problème? Si non, pouvez-vous fournir votre code qui vous cause le problème? –

+18

+++ 1, cela devrait être la bonne réponse marquée comme maintenant –

4

Vous pouvez mettre en œuvre cette nouvelle avec une fonction d'extension d'aide Html qui sera ensuite utilisé de manière similaire aux ActionLinks existants.

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 l'appelez 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 écriture here

57

C'est encore plus facile que tout ce qui est suggéré ci-dessus. Les attributs de données dans MVC qui incluent des tirets (-) sont pris en charge avec l'utilisation du trait de soulignement (_).

<%= 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é ceci.

+12

la méthode responsable de c'est: HtmlHel. per.AnonymousObjectToHtmlAttributes (objet), au cas où quelqu'un se demanderait pourquoi son extension personnalisée ne remplacera pas le trait de soulignement par un trait d'union. – Nikkelmann

+1

Cela a vraiment besoin d'être voté car c'est de loin la réponse la plus simple et fonctionne parfaitement! –

-3

Vous pouvez l'utiliser comme ceci:

En Mvc:

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

Html:

<input type="text" name="Id" data_val_number="10"/> 
14

En mvc 4 pourrait être rendu avec soulignement (» _ ")

Razor:

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

Rendus Html

<a class="votes" data-fid="18587" data-jid="9" href="/Home/%23/18587">Vote</a> 
+0

Salut, existe-t-il un moyen de POST la donnée-fid au contrôleur, via un Ajax ou soumettre. Je me demande comment exploiter les données. Par exemple, si j'avais un 'data-date' dans l'attribut, comment pourrais-je l'afficher sur le contrôleur/l'action? Aussi ce qui est% 23 là – transformer

+0

Oui utiliser la collection de formulaires et y accéder avec un ID ou un nom, et% 23 est # – mzonerz

Questions connexes