2011-07-09 33 views
9

Tôi muốn thêm một lỗi ModelState, như vậy:Làm thế nào để bao gồm một liên kết trong thông báo AddModelError?

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

Tuy nhiên, liên kết không được mã hóa, và do đó sẽ được hiển thị như văn bản. Tôi đã cố gắng sử dụng

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

thay vì

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

Nhưng không may mắn.

Bất kỳ ai có ý tưởng về cách làm việc này?

Chúc mừng

Trả lời

5

Trình trợ giúp ValidationSummary tự động HTML mã hóa tất cả thư. Một cách giải quyết có thể là viết một bản tóm tắt helper xác nhận tùy chỉnh mà không HTML mã hóa các thông điệp:

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

và sau đó:

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

Dĩ nhiên bằng cách làm này bạn nên cẩn thận như những gì văn bản bạn đang đưa vào những thông báo lỗi như bây giờ họ sẽ không được mã hóa HTML. Điều này có nghĩa là nếu bạn muốn sử dụng một số ký tự đặc biệt như <, >, & vào thư của mình, bạn sẽ cần phải tự mã hóa HTML hoặc đánh dấu sẽ bị hỏng.

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> 

hoặc dao cạo:

<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

Cách đơn giản nhất (cũng làm việc với MVC 4):

Trong điều khiển:

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

Theo quan điểm:

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

Đây phải là câu trả lời được chấp nhận vì nó sạch, súc tích và hoạt động tốt. Cảm ơn – maxshuty

+0

Rất dễ sử dụng. Cảm ơn! – Quiver

Các vấn đề liên quan