2010-08-11 14 views
67

ho qualche dubbio su come concatenare le istanze MvcHtmlString a causa di questo informazioni che si trovano in MSDN:come concatenare diverse istanze MvcHtmlString

MvcHtmlString Classe Rappresenta una stringa HTML con codifica che non dovrebbe essere codificato di nuovo

posso rischiare che le stringhe sono HTML-codificati due volte quando si utilizza il codice come questo:

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

(nota: questo dovrebbe entrare in un metodo di estensione HtmlHelper per ridurre la duplicazione del codice nelle viste).

risposta

26

Il tuo codice è corretto.

Questo frammento di MSDN significa che un motore di visualizzazione di codifica (come il motore di visualizzazione Aspx in .NET 4 quando si utilizza <%: %> o il motore di visualizzazione Razor in MVC 3) non deve ricodificare il valore di stringa dell'oggetto.

Così, per esempio:

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

<%: s %> -- outputs "&lt;tag&gt;" 
<%: hs %> -- outputs "<tag>" 
57

Peccato C# non ci permetterà di ridefinire l'operatore + qui! Che ne dici invece di utilizzare un metodo di estensione?

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

Questo potrebbe probabilmente essere ottimizzato, ma è possibile eseguire con esso. Dovrebbe essere abbastanza semplice dimostrare che questo non raddoppia le stringhe con un test unitario.

campione Uso:

label.Concat(textbox, validation) 

E ora una spina spudorato per il mio blog: Use TagBuilder or HtmlTags to clean up your HTML

+2

Questo non viene compilato per me, ho cambiato: \t public static MvcHtmlString Concat (questo MvcHtmlString prima, PARAMS MvcHtmlString [] stringhe) \t { \t \t return MvcHtmlString.Create (first.ToString() + string.Concat (stringhe.Select (s => s.ToString()). ToArray())); \t} – Charlie

+0

c'è un motivo per cui i parametri di input non sono 'IHtmlString'? – Maslow

+1

IHtmlString non esisteva in.NET 3.5 – Ryan

19

sono andato per questo approccio:

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

E 'solo un metodo di utilità che uso interno le classi con i metodi di estensione per HtmlHelper.

0

So che questo è super vecchio, ma ancora un altro modo (che trovo ad essere più elegante), è quello di utilizzare un overload del metodo String Concat, quale definizione di metadati è

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

che, in fondo ToStrings ognuno degli oggetti passati e quindi concatena i risultati e restituisce la stringa concatenata.

Così il risultato finale sarebbe:

var result = MvcHtmlString.Create(
    string.Concat(
     label, textbox, validation 
    ) 
); 
Problemi correlati