So verketten Sie mehrere MvcHtmlString-Instanzen

68

Ich habe einige Zweifel, wie MvcHtmlString-Instanzen aufgrund dieser Informationen in MSDN verkettet werden können :

MvcHtmlString-Klasse Stellt eine HTML-codierte Zeichenfolge dar, die nicht erneut codiert werden sollte

Riskiere ich, dass Zeichenfolgen bei Verwendung von Code wie diesem zweimal HTML-codiert werden:

var label = Html.LabelFor(model => model.Email);
var textbox = Html.TextBoxFor(model => model.Email);
var validation = Html.ValidationMessageFor(model => model.Email);

var result = MvcHtmlString.Create(
  label.ToString() + textbox.ToString() + validation.ToString());

(Hinweis: Dies soll in eine HtmlHelper-Erweiterungsmethode gehen, um die Codeduplizierung in Ansichten zu reduzieren.)

M4N
quelle

Antworten:

27

Ihr Code ist korrekt.

Dieses Snippet aus MSDN bedeutet, dass eine codierende View Engine (z. B. die Aspx View Engine in .NET 4 bei Verwendung <%: %>oder die Razor View Engine in MVC 3) den Zeichenfolgenwert des Objekts nicht neu codieren sollte.

Also zum Beispiel:

string s = "<tag>";
var hs = MvcHtmlString.Create(s);

<%: s %>  -- outputs "&lt;tag&gt;"
<%: hs %> -- outputs "<tag>"
Marcind
quelle
58

Schade, dass C # uns den Operator + hier nicht überschreiben lässt! Wie wäre es stattdessen mit einer Erweiterungsmethode?

public static MvcHtmlString Concat(this MvcHtmlString first, params MvcHtmlString[] strings)
{
    return MvcHtmlString.Create(first.ToString() + string.Concat(strings.Select(s => s.ToString())));
}

Dies könnte wahrscheinlich optimiert werden, aber Sie können damit laufen. Es sollte ziemlich trivial sein zu beweisen, dass dies Strings mit einem Unit-Test nicht doppelt codiert.

Anwendungsbeispiel:

label.Concat(textbox, validation)   

Und jetzt ein schamloser Plug für mein Blog: Verwenden Sie TagBuilder oder HtmlTags, um Ihren HTML-Code zu bereinigen

Ryan
quelle
2
Dies wird für mich nicht kompiliert, ich habe es geändert: public static MvcHtmlString Concat (dieser MvcHtmlString zuerst, Parameter MvcHtmlString [] Strings) {return MvcHtmlString.Create (first.ToString () + string.Concat (strings.Select (s) => s.ToString ()). ToArray ())); }
Charlie
Gibt es einen Grund, warum die Eingabeparameter nicht sind IHtmlString?
Maslow
1
IHtmlString existierte nicht in .NET 3.5
Ryan
21

Ich habe mich für diesen Ansatz entschieden:

    private static MvcHtmlString Concat(params MvcHtmlString[] items)
    {
        var sb = new StringBuilder();
        foreach (var item in items.Where(i => i != null))
            sb.Append(item.ToHtmlString());
        return MvcHtmlString.Create(sb.ToString());
    }

Es ist nur eine Dienstprogrammmethode, die ich in den Klassen mit Erweiterungsmethoden für HtmlHelper verwende.

miguelv
quelle
4

Ich weiß, dass dies super alt ist, aber eine andere Möglichkeit (die ich eleganter finde) besteht darin, eine Überladung der String-Methode Concat zu verwenden, die Metadatendefinition ist

public static String Concat(params object[] args);

dass ToStrings im Grunde jedes der übergebenen Objekte und dann die Ergebnisse verkettet und die verkettete Zeichenfolge zurückgibt.

Das Endergebnis wäre also:

var result = MvcHtmlString.Create(
    string.Concat(
        label, textbox, validation
    )
);
Nahuel Prieto
quelle