2011-07-09 22 views
9

我想添加的ModelState錯誤,像這樣:如何在AddModelError消息中包含鏈接?

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

但是,鏈接不會被編碼,因此顯示像文本。我試着用

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

代替

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

,但沒有運氣。

任何人有任何想法如何得到這個工作?

Cheers

回答

5

ValidationSummary helper自動對所有消息進行HTML編碼。一個可能的解決方法是編寫一個自定義的驗證摘要幫手不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); 
    } 
} 

然後:

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

當然做這個,你應該小心,因爲什麼,你的文字正在放入這些錯誤消息,因爲現在它們不會被HTML編碼。這意味着如果您想要在郵件中使用某些特殊字符(例如<,>,&),您需要自己對HTML進行編碼,否則標記將會中斷。

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> 

或在剃刀:

<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

的simpliest方式(工作也與MVC 4):

在控制器:

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

鑑於:

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

這應該是公認的答案,因爲它乾淨,簡潔,並且運作良好。謝謝 – maxshuty

+0

非常容易使用。謝謝! – Quiver

相關問題