/// <inheritdoc /> public virtual TagBuilder GenerateValidationSummary( [NotNull] ViewContext viewContext, bool excludePropertyErrors, string message, string headerTag, object htmlAttributes) { var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null; if (viewContext.ViewData.ModelState.IsValid && (formContext == null || excludePropertyErrors)) { // No client side validation/updates return(null); } string wrappedMessage; if (!string.IsNullOrEmpty(message)) { if (string.IsNullOrEmpty(headerTag)) { headerTag = viewContext.ValidationSummaryMessageElement; } var messageTag = new TagBuilder(headerTag); messageTag.SetInnerText(message); wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine; } else { wrappedMessage = null; } // If excludePropertyErrors is true, describe any validation issue with the current model in a single item. // Otherwise, list individual property errors. var htmlSummary = new StringBuilder(); var modelStates = ValidationHelpers.GetModelStateList(viewContext.ViewData, excludePropertyErrors); foreach (var modelState in modelStates) { foreach (var modelError in modelState.Errors) { var errorText = ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState: null); if (!string.IsNullOrEmpty(errorText)) { var listItem = new TagBuilder("li"); listItem.SetInnerText(errorText); htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal)); } } } if (htmlSummary.Length == 0) { htmlSummary.AppendLine(HiddenListItem); } var unorderedList = new TagBuilder("ul") { InnerHtml = htmlSummary.ToString() }; var tagBuilder = new TagBuilder("div"); tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes)); if (viewContext.ViewData.ModelState.IsValid) { tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryValidCssClassName); } else { tagBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName); } tagBuilder.InnerHtml = wrappedMessage + unorderedList.ToString(TagRenderMode.Normal); if (formContext != null && !excludePropertyErrors) { // Inform the client where to replace the list of property errors after validation. tagBuilder.MergeAttribute("data-valmsg-summary", "true"); } return(tagBuilder); }
/// <inheritdoc /> public virtual TagBuilder GenerateValidationMessage( [NotNull] ViewContext viewContext, string name, string message, string tag, object htmlAttributes) { var fullName = GetFullHtmlFieldName(viewContext, name); if (string.IsNullOrEmpty(fullName)) { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "expression"); } var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null; if (!viewContext.ViewData.ModelState.ContainsKey(fullName) && formContext == null) { return(null); } ModelState modelState; var tryGetModelStateResult = viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState); var modelErrors = tryGetModelStateResult ? modelState.Errors : null; ModelError modelError = null; if (modelErrors != null && modelErrors.Count != 0) { modelError = modelErrors.FirstOrDefault(m => !string.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]; } if (modelError == null && formContext == null) { return(null); } // Even if there are no model errors, we generate the span and add the validation message // if formContext is not null. if (string.IsNullOrEmpty(tag)) { tag = viewContext.ValidationMessageElement; } var tagBuilder = new TagBuilder(tag); tagBuilder.MergeAttributes(GetHtmlAttributeDictionaryOrNull(htmlAttributes)); // Only the style of the span is changed according to the errors if message is null or empty. // Otherwise the content and style is handled by the client-side validation. var className = (modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName; tagBuilder.AddCssClass(className); if (!string.IsNullOrEmpty(message)) { tagBuilder.SetInnerText(message); } else if (modelError != null) { tagBuilder.SetInnerText(ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState)); } if (formContext != null) { tagBuilder.MergeAttribute("data-valmsg-for", fullName); var replaceValidationMessageContents = string.IsNullOrEmpty(message); tagBuilder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant()); } return(tagBuilder); }