339 Stimmen

Verwendung von Bindestrichen in HTML-5 data-* Attributen in ASP.NET MVC

Ich versuche zu verwenden HTML5 Daten-Attribute in meinem ASP.NET MVC 1 Projekt. (Ich bin ein C# und ASP.NET MVC Neuling.)

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

Die "data-details" in den oben genannten htmlAttributes führen zu dem folgenden Fehler:

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

Es funktioniert, wenn ich data_details verwende, aber ich denke, es muss mit "data-" beginnen, wie in der Spezifikation angegeben.

Meine Fragen:

  • Gibt es eine Möglichkeit, dies zu erreichen und HTML5-Datenattribute mit Html.ActionLink oder ähnlichen Html-Hilfsmitteln zu verwenden?
  • Gibt es einen anderen Mechanismus, um benutzerdefinierte Daten an ein Element anzuhängen? Diese Daten sollen später von JS verarbeitet werden.

667voto

Johnny Oshika Punkte 49503

Dieses Problem wurde in ASP.Net MVC 3 behoben. Jetzt werden Unterstriche in HTML-Attribut-Eigenschaften automatisch in Bindestriche umgewandelt. Dabei hatten sie Glück, denn Unterstriche sind in HTML-Attributen nicht zulässig, so dass MVC getrost davon ausgehen kann, dass Sie einen Bindestrich möchten, wenn Sie einen Unterstrich verwenden.

Zum Beispiel:

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

wird dies in MVC 3 wiedergeben:

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

Wenn Sie noch eine ältere Version von MVC verwenden, können Sie nachahmen, was MVC 3 tut, indem Sie diese statische Methode erstellen, die ich aus dem Quellcode von MVC3 entlehnt habe:

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

Und dann können Sie es so verwenden:

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

und dies wird das richtige data-*-Attribut wiedergeben:

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

118voto

Morten Mertner Punkte 9284

Update: MVC 3 und neuere Versionen haben integrierte Unterstützung für diese. Siehe JohnnyOs hoch bewertete Antwort unten für empfohlene Lösungen.

Ich glaube nicht, dass es dafür unmittelbare Hilfsmittel gibt, aber ich habe zwei Ideen, die Sie ausprobieren können:

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

Das sind nur Ideen, ich habe es nicht getestet.

61voto

Oliver Punkte 33151

Es ist sogar noch einfacher als alles, was oben vorgeschlagen wurde. Datenattribute in MVC, die Bindestriche (-) enthalten, werden durch die Verwendung von Unterstrichen (_) abgedeckt.

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

Wie ich sehe, hat JohnnyO dies bereits erwähnt.

28voto

mzonerz Punkte 1180

In mvc 4 könnte mit Underscore(" _ ") gerendert werden

Rasierklinge:

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

Gerendertes Html

<a class="votes" data-fid="18587" data-jid="9" href="http://stackoverflow.com/Home/%23/18587">Vote</a>

4voto

WestDiscGolf Punkte 4088

Sie können dies mit einer neuen Html-Helper-Erweiterungsfunktion implementieren, die dann ähnlich wie die bestehenden ActionLinks verwendet wird.

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

Und du nennst es so ...

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

Ganz einfach :-)

bearbeiten

etwas ausführlicherer Bericht aquí

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X