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” ?
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
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="border:0px"
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=""border:0px""
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.
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).