2011-07-09 9 views
9

Quiero añadir un error de ModelState, así:¿Cómo incluir un enlace en el mensaje AddModelError?

ModelState.AddModelError("", "Some message, <a href="/controller/action">click here</a>) 

Sin embargo, el enlace no consigue codificado, y así se muestra como texto. He intentado utilizar

<%= Html.ValidationSummary(true, "Some message") 

en lugar de

<%: Html.ValidationSummary(true, "Some message") 

Pero no hubo suerte.

¿Alguien tiene alguna idea de cómo hacerlo funcionar?

Saludos

Respuesta

5

El ayudante ValidationSummary automáticamente HTML codifica todos los mensajes. Una posible solución consiste en escribir un ayudante Resumen de validación costumbre que no codificar los mensajes HTML:

public static class HtmlExtensions 
{ 
    public static MvcHtmlString MyValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message) 
    { 
     var formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null; 
     if (formContext == null && htmlHelper.ViewData.ModelState.IsValid) 
     { 
      return null; 
     } 

     string messageSpan; 
     if (!string.IsNullOrEmpty(message)) 
     { 
      TagBuilder spanTag = new TagBuilder("span"); 
      spanTag.SetInnerText(message); 
      messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine; 
     } 
     else 
     { 
      messageSpan = null; 
     } 

     var htmlSummary = new StringBuilder(); 
     TagBuilder unorderedList = new TagBuilder("ul"); 

     IEnumerable<ModelState> modelStates = null; 
     if (excludePropertyErrors) 
     { 
      ModelState ms; 
      htmlHelper.ViewData.ModelState.TryGetValue(htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, out ms); 
      if (ms != null) 
      { 
       modelStates = new ModelState[] { ms }; 
      } 
     } 
     else 
     { 
      modelStates = htmlHelper.ViewData.ModelState.Values; 
     } 

     if (modelStates != null) 
     { 
      foreach (ModelState modelState in modelStates) 
      { 
       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.InnerHtml = errorText; 
         htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal)); 
        } 
       } 
      } 
     } 

     if (htmlSummary.Length == 0) 
     { 
      htmlSummary.AppendLine(@"<li style=""display:none""></li>"); 
     } 

     unorderedList.InnerHtml = htmlSummary.ToString(); 

     TagBuilder divBuilder = new TagBuilder("div"); 
     divBuilder.AddCssClass((htmlHelper.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName); 
     divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal); 

     if (formContext != null) 
     { 
      // client val summaries need an ID 
      divBuilder.GenerateId("validationSummary"); 
      formContext.ValidationSummaryId = divBuilder.Attributes["id"]; 
      formContext.ReplaceValidationSummary = !excludePropertyErrors; 
     } 
     return MvcHtmlString.Create(divBuilder.ToString()); 
    } 

    private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState) 
    { 
     if (!String.IsNullOrEmpty(error.ErrorMessage)) 
     { 
      return error.ErrorMessage; 
     } 
     if (modelState == null) 
     { 
      return null; 
     } 

     string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null; 
     return String.Format(CultureInfo.CurrentCulture, "The value {0} is invalid.", attemptedValue); 
    } 
} 

y luego:

<%= Html.MyValidationSummary(true, "Some message") %> 

Por supuesto, al hacer esto se debe tener cuidado ya que lo que el texto están poniendo esos mensajes de error ya que ahora no estarán codificados en HTML. Esto significa que si alguna vez quisiste utilizar algunos caracteres especiales como <, >, & en tu mensaje, necesitarás codificarlo HTML tú mismo o el marcado se romperá.

3
<div class="validation-summary-errors"> 
    <ul> 
    <% foreach(var error in ViewData.ModelState.Where(s => s.Value.Errors.Count!=0).SelectMany(s => s.Value.Errors)) { %> 
     <li><%= error.ErrorMessage %></li> 
    <% } %> 
    </ul> 
</div> 

o en la maquinilla de afeitar:

<div class="validation-summary-errors"> 
    <ul> 
    @foreach(var error in ViewData.ModelState.Where(s => s.Value.Errors.Count!=0).SelectMany(s => s.Value.Errors)) { 
     <li>@Html.Raw(error.ErrorMessage)</li> 
    } 
    </ul> 
</div> 
18

La forma más simple (funciona también con MVC 4):

En controlador:

ModelState.AddModelError("", "Please click <a href=\"http://stackoverflow.com\">here</a>"); 

En vista:

if (ViewData.ModelState.Any(x => x.Value.Errors.Any())) 
{ 
@Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary().ToHtmlString())) 
} 
+1

Esta debería ser la respuesta aceptada, ya que es limpia, concisa y funciona bien. Gracias – maxshuty

+0

Muy fácil de usar. ¡Gracias! – Quiver

Cuestiones relacionadas