Bedingte HTML-Attribute mit Razor

Lesezeit: 7 Minuten

Benutzeravatar von tony722
tony722

Die Variable strCSSClass hat oft einen Wert, ist aber manchmal leer.

Ich möchte kein leeres class=”” in den HTML-Code dieses Eingabeelements einfügen, d. h. wenn strCSSClass leer ist, möchte ich das class=-Attribut überhaupt nicht.

Das Folgende ist eine Möglichkeit, ein bedingtes HTML-Attribut auszuführen:

<input type="text" id="@strElementID" @(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />

Gibt es eine elegantere Möglichkeit, dies zu tun? Insbesondere eine, bei der ich der gleichen Syntax folgen könnte, die in den anderen Teilen des Elements verwendet wird: class=”@strCSSClass” ?

Benutzeravatar von Erik Porter
Erik Porter

Sie haben es nicht von mir gehört, dem PM für Razor, aber in Razor 2 (Web Pages 2 und MVC 4) haben wir bedingte Attribute in Razor eingebaut (ab MVC 4 RC erfolgreich getestet), damit Sie Dinge schreiben können so was:

<input type="text" id="@strElementID" class="@strCSSClass" />

Wenn strCSSClass null ist, wird das Klassenattribut überhaupt nicht gerendert.

Weiterführende Lektüre

  • Ja, Sie sollten meine definitiv nicht als Antwort akzeptieren. Allerdings gibt es heute keinen saubereren Weg, dies zu tun (daher schaffen wir einen saubereren Weg, dies zu tun). Der wahrscheinlich sauberste Weg, dies zu tun, ist die Verwendung von Html.TextBox, aber das hat einen anderen Satz weniger wünschenswerter Dinge. 🙁 Freut mich aber, dass dir gefällt, was wir hinzufügen. 🙂

    – Erik Porter

    16. November 2011 um 23:07 Uhr

  • Aber wie kann ich Razor-Attribute mit anderem Text kombinieren? Ich muss Folgendes machen: … id=”[email protected]”. Ich habe etwas wie …id=”track_2″ erwartet, aber es hat die folgende Ausgabe generiert: …id=”[email protected]”…

    – Laserson

    15. Januar 2012 um 17:57 Uhr

  • Sie können Razor dazu zwingen, Code auszuwerten, indem Sie ihn in Klammern setzen. id=”[email protected](track.ID)”

    – Erik Porter

    27. Januar 2012 um 18:42 Uhr

  • Hinweis hinzugefügt, dass dies erfolgreich mit MVC 4 funktioniert. Wenn Sie MVC 3 verwenden, lesen Sie meine Antwort unten.

    – AaronLS

    6. November 2012 um 20:29 Uhr

  • @ErikPorter BITTE NICHT MIT MEINEM HTML FIELEN!! siehe auch stackoverflow.com/questions/9234467/… dies auch für anderes schlechtes Verhalten

    – Adlersturm

    15. Januar 2014 um 0:04 Uhr

Benutzeravatar von AaronLS
AaronLS

Beachten Sie, dass Sie so etwas tun können (zumindest in MVC3):

<td align="left" @(isOddRow ? "class=TopBorder" : "style=border:0px") >

Was ich für das Hinzufügen von Anführungszeichen hielt, war eigentlich der Browser. Wie Rism beim Testen mit MVC 4 betonte (ich habe nicht mit MVC 3 getestet, aber ich gehe davon aus, dass sich das Verhalten nicht geändert hat), erzeugt dies tatsächlich class=TopBorder aber Browser sind in der Lage, dies gut zu analysieren. Die HTML-Parser verzeihen etwas fehlende Attribut-Anführungszeichen, aber Dies kann brechen, wenn Sie Leerzeichen oder bestimmte Zeichen haben.

<td align="left" class="TopBorder" >

ODER

<td align="left" style="border:0px" >

Was läuft schief, wenn Sie Ihre eigenen Angebote erstellen?

Wenn Sie versuchen, einige der üblichen C#-Konventionen für verschachtelte Anführungszeichen zu verwenden, erhalten Sie am Ende mehr Anführungszeichen, als Sie erwartet hatten, da Razor versucht, sie sicher zu umgehen. Zum Beispiel:

<button type="button" @(true ? "style=\"border:0px\"" : string.Empty)>

Dies sollte auswerten zu <button type="button" style="border:0px"> aber Razor maskiert alle Ausgaben von C# und erzeugt somit:

style=&quot;border:0px&quot;

Sie sehen dies nur, wenn Sie die Antwort über das Netzwerk anzeigen. Wenn Sie einen HTML-Inspektor verwenden, sehen Sie oft tatsächlich das DOM und nicht das rohe HTML. Browser parsen HTML in das DOM, und die After-Parsing-DOM-Darstellung hat bereits einige Feinheiten angewendet. In diesem Fall sieht der Browser, dass der Attributwert nicht in Anführungszeichen steht, und fügt sie hinzu:

style="&quot;border:0px&quot;"

Aber im DOM-Inspektor werden HTML-Zeichencodes richtig angezeigt, sodass Sie tatsächlich Folgendes sehen:

style=""border:0px""

Wenn Sie in Chrome mit der rechten Maustaste klicken und HTML bearbeiten auswählen, wechseln Sie zurück, damit Sie diese bösen HTML-Zeichencodes sehen können, wodurch deutlich wird, dass Sie echte äußere Anführungszeichen und HTML-codierte innere Anführungszeichen haben.

Das Problem beim Versuch, selbst zu zitieren, besteht also darin, dass Razor diesen entgeht.

Wenn Sie die vollständige Kontrolle über die Angebote wünschen

Verwenden Sie Html.Raw, um das Entkommen von Zitaten zu verhindern:

<td @Html.Raw( someBoolean ? "rel="tooltip" data-container=".drillDown a"" : "" )>

Rendert als:

<td rel="tooltip" title="Drilldown" data-container=".drillDown a">

Das Obige ist absolut sicher, da ich kein HTML von einer Variablen ausgebe. Die einzige beteiligte Variable ist die ternäre Bedingung. Jedoch, in acht nehmen dass diese letzte Technik Sie bestimmten Sicherheitsproblemen aussetzen könnte, wenn Sie Zeichenfolgen aus vom Benutzer bereitgestellten Daten erstellen. Wenn Sie z. B. ein Attribut aus Datenfeldern erstellt haben, die aus vom Benutzer bereitgestellten Daten stammen, bedeutet die Verwendung von Html.Raw, dass die Zeichenfolge ein vorzeitiges Ende des Attributs und des Tags enthalten und dann ein Skript-Tag beginnen könnte, das etwas im Namen des derzeit angemeldeten Benutzers tut Benutzer (möglicherweise anders als der angemeldete Benutzer). Vielleicht haben Sie eine Seite mit einer Liste aller Benutzerbilder und Sie legen einen Tooltip fest, der den Benutzernamen jeder Person enthält, und einen Benutzer, der sich selbst nennt '/><script>$.post('changepassword.php?password=123')</script> und jetzt wird das Passwort jedes anderen Benutzers, der diese Seite anzeigt, sofort in ein Passwort geändert, das der böswillige Benutzer kennt.

  • Das ist ein sehr guter Punkt! Und tatsächlich macht es es in den meisten Situationen lesbar und verwendbar.

    – Dmytro Schewtschenko

    1. Mai 2012 um 6:53 Uhr


  • Das habe ich in dem Beispiel in meiner Frage getan. Danke für eine ausführlichere Erklärung und ein Beispiel. 🙂

    – tony722

    1. Juni 2012 um 0:23 Uhr

  • Achten Sie jedoch auf Leerzeichen. “Stil = Anzeige: keine;” rendert als none;=”” :=”” style=”display”

    – wmcainsh

    30. Januar 2013 um 12:17 Uhr


  • Warum funktioniert das nicht in Bezug auf: magische doppelte Anführungszeichen Es wird nur erzeugt

    – Risiko

    29. Januar 2015 um 0:19 Uhr

  • @AaronLS Ja, genau so sind sie. Ich kann nicht verstehen, wie sich der Browser (Chrome 40/FF33.1/IE 10) auf irgendetwas auswirken würde, da dies ein vom Server generiertes Markup ist, und wenn ja, warum nur diese beiden Klassenattribute, aber nicht das Klassenattribut der Ask-Schaltfläche oder sogar der Typ= “button”-Attribute aller drei Buttons. Meiner Meinung nach definitiv eine Serversache, da ich auch RDP in ein paar virtuelle Azure-Maschinen auf der ganzen Welt für das gleiche Ergebnis IE/Firefox/Chrome verwenden kann.

    – Risiko

    29. Januar 2015 um 3:50 Uhr

Ich denke, ein etwas bequemerer und strukturierterer Weg ist die Verwendung des Html-Helfers. Aus Ihrer Sicht kann es so aussehen:

@{
 var htmlAttr = new Dictionary<string, object>();
 htmlAttr.Add("id", strElementId);
 if (!CSSClass.IsEmpty())
 {
   htmlAttr.Add("class", strCSSClass);
 }
}

@* ... *@

@Html.TextBox("somename", "", htmlAttr)

Wenn dieser Weg für Sie nützlich ist, empfehle ich, das Wörterbuch zu definieren htmlAttr in Ihrem Modell, damit Ihre Ansicht keine benötigt @{ } Logikblöcke (klarer sein).

  • -1, niemals jemandem empfehlen, Logik in die Ansichten einzubauen. Die Ansichten sollten nur für das Rendern zuständig sein. Fügen Sie stattdessen ein HtmlHelper-Beispiel hinzu und ich gebe Ihnen +1.

    – jgauffin

    9. November 2011 um 8:13 Uhr


  • Um Dinge zu testen, kann ich den Codeblock in der Ansicht verwenden – es ist schneller. Und meine Empfehlung war, diesen Block in das Modell zu verschieben.

    – Jaschur

    9. November 2011 um 8:24 Uhr

  • Ja, aber die Antworten sollten die Best Practice zeigen und nicht die schnelle und schmutzige Version, die die Codewartung zu einem Alptraum macht.

    – jgauffin

    9. November 2011 um 8:28 Uhr

  • @jgauffin Ich denke, HTML-Helfer hier ist unnötig. siehe meine antwort.

    – gdoron unterstützt Monica

    9. November 2011 um 9:49 Uhr

  • +1 @Yaschur Ihre Antwort ist inspirierend. Mach weiter so. dh. Mit der expliziten Konvertierungsfunktion von C# können wir diese Antwort noch weiter verbessern. Nicht der gesamte Code musste auf eine bestimmte Weise geformt sein. Es gibt immer einen besseren Weg, den wir nicht kennen. Und einige Projekte befürworten die Code-Organisation. Code-Organisationen sind praktisch keine Konzepte!

    – Bambus

    28. Dezember 2012 um 10:41 Uhr


1429790cookie-checkBedingte HTML-Attribute mit Razor

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy