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.)

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>"

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


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.


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
    )
);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.