Come visualizzare elementi html come link in errori resi tramite Html.ValidationSummary ()

Uno dei miei messaggi di errore rende un collegamento. Tuttavia, Html.ValidationSummary() codifica e pertanto viene visualizzato come segue:

Esiste già un account con il cellulare o l’e-mail che hai specificato. Se hai dimenticato la password, Reimposta it.

Invece, dovrebbe rendere come:

Esiste già un account con il cellulare o l’e-mail che hai specificato. Se hai dimenticato la password, resetta.

L’errore viene aggiunto alla vista interna ModelState come segue:

 if (...) { ViewData.ModelState.AddModelError(string.Empty, string.Format("An account with the mobile or email you have specified already exists. If you have forgotten your password, please {0} it.", Html.ActionLink("Reset", "Reset"))); } 

In breve, come dovrei impedire a Html.ValidationSummarry() di codificare in modo selettivo / interamente HTML in errori.

Gli attuali helper HTML per la visualizzazione dei messaggi di errore non supportano questo. Tuttavia, è ansible scrivere i propri helper HTML che visualizzano il messaggio di errore senza che l’HTML lo sfugga, ovvero trattano il messaggio di errore come HTML non elaborato.

Come punto di partenza, è ansible utilizzare il codice sorgente ASP.NET MVC da Codeplex, in particolare il metodo ValidationExtensions class ValidationExtensions :

  public static string ValidationSummary(this HtmlHelper htmlHelper, string message, IDictionary htmlAttributes) { // Nothing to do if there aren't any errors if (htmlHelper.ViewData.ModelState.IsValid) { return null; } string messageSpan; if (!String.IsNullOrEmpty(message)) { TagBuilder spanTag = new TagBuilder("span"); spanTag.MergeAttributes(htmlAttributes); spanTag.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName); spanTag.SetInnerText(message); messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine; } else { messageSpan = null; } StringBuilder htmlSummary = new StringBuilder(); TagBuilder unorderedList = new TagBuilder("ul"); unorderedList.MergeAttributes(htmlAttributes); unorderedList.MergeAttribute("class", HtmlHelper.ValidationSummaryCssClassName); foreach (ModelState modelState in htmlHelper.ViewData.ModelState.Values) { foreach (ModelError modelError in modelState.Errors) { string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */); if (!String.IsNullOrEmpty(errorText)) { TagBuilder listItem = new TagBuilder("li"); listItem.SetInnerText(errorText); htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal)); } } } unorderedList.InnerHtml = htmlSummary.ToString(); return messageSpan + unorderedList.ToString(TagRenderMode.Normal); } 

È quindi ansible modificare questo metodo per trattare il messaggio di errore come HTML non elaborato.

Due avvertimenti però:

  1. Stai cambiando il significato di alcune proprietà della class ModelState . Mentre si utilizza subito i propri helper HTML, una versione futura di ASP.NET MVC potrebbe introdurre modifiche che non funzionano più con questo approccio.

  2. Fai molta attenzione a non utilizzare i messaggi di errore che non sono correttamente fugati, in modo da non esporre la tua app Web agli attacchi XSS. Alcune annotazioni di convalida standard potrebbero non funzionare più poiché non eseguono l’escape del messaggio di errore in HTML.