web-dev-qa-db-fra.com

Comment utiliser les tirets dans les attributs HTML- 5 data- * dans ASP.NET MVC

J'essaie d'utiliser attributs de données HTML5 dans mon projet ASP.NET MVC 1. (Je suis un débutant en C # et 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 donnent l'erreur suivante:

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

Cela fonctionne lorsque j'utilise data_details, mais je suppose que cela doit commencer par "data-" conformément à la spécification.

Mes questions:

  • Existe-t-il un moyen de faire en sorte que cela fonctionne et d'utiliser les attributs de données HTML5 avec Html.ActionLink ou des aides HTML similaires?
  • 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.
314
Shameem

Mise à jour: MVC 3 et les versions plus récentes ont un support intégré pour cela. Voir la réponse très élevée de JohnnyO ci-dessous pour les solutions recommandées.

Je ne pense pas qu’il y ait des aides immédiats pour y parvenir, mais j’ai deux idées que vous pouvez 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, je ne l'ai pas testé.

114
Morten Mertner

Ce problème a été résolu dans ASP.Net MVC 3. Ils convertissent désormais automatiquement les traits de soulignement dans les propriétés d'attribut html en tirets. Ils ont eu de la chance avec celui-ci, car les traits de soulignement ne sont pas légaux dans les attributs HTML, donc MVC peut impliquer en toute 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 toujours une ancienne version de MVC, vous pouvez imiter ce que fait MVC 3 en créant cette méthode statique que j'ai empruntée au 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 ça:

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

et cela rendra l'attribut data- * correct:

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

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 compte 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 que JohnnyO a déjà mentionné cela.

58
Oliver

Dans mvc 4 Pourrait être rendu avec un trait de soulignement ("_")

Rasoir:

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

rendu HTML

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

Vous pouvez implémenter cela avec une nouvelle fonction d’extension d’aide HTML qui sera ensuite utilisée de la même manière que les 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 ici

4
WestDiscGolf

J'ai fini par utiliser un hyperlien normal 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 laid, mais vous avez un peu plus de contrôle sur la balise a, qui est parfois utile dans les sites fortement AJAXified.

HTH

3
Keith Williams

Je n'aime pas utiliser pur "a" tag, trop de frappe. Alors je viens avec la solution. En vue il regarde

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

Implémentation 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));
    }
}
0
msa7