2011-07-09 11 views
9

chcę dodać błąd ModelState, tak:Jak dołączyć łącze do wiadomości AddModelError?

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

Jednak związek nie zostanie zakodowany, i tak jak jest wyświetlany tekst. Próbowałem za pomocą

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

zamiast

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

ale bez powodzenia.

Ktoś ma pojęcie, jak to działa?

Cheers

Odpowiedz

5

ValidationSummary pomocnik automatycznie koduje HTML wszystkie wiadomości. Jednym z możliwych rozwiązaniem jest napisać zwyczaj sprawdzania Podsumowanie pomocnika, który nie HTML zakodować wiadomości:

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

, a następnie:

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

Oczywiście robiąc to należy być ostrożnym, jak to, co tekstu wstawiają się do tych komunikatów o błędach, ponieważ teraz nie będą one kodowane w HTML. Oznacza to, że jeśli kiedykolwiek chciałeś użyć specjalnych znaków, takich jak <, >, & do swojej wiadomości, będziesz musiał sam je zakodować HTML lub znacznik się zepsuje.

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> 

lub maszynki:

<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

najprostszy sposób (współpracuje również z MVC 4)

W regulatora:

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

Ze względu:

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

To powinna być zaakceptowana odpowiedź, ponieważ jest czysta, zwięzła i działa dobrze. Dzięki – maxshuty

+0

Bardzo łatwy w użyciu. Dzięki! – Quiver

Powiązane problemy