From a6d89c44822a725497758d1dc9a15c1d5bdb3517 Mon Sep 17 00:00:00 2001 From: Tian Pan Date: Tue, 13 May 2014 20:33:58 -0700 Subject: [PATCH] Copy CodePlex #1836 and #1878 fixes over (Fix #296). This change enables user to specify the tag for the wrapping HTML element generated from ValidationSummary() and ValidationMessage[For](). Clean up HtmlHelperValidationExtensions. --- .../Views/Home/ValidationSummary.cshtml | 4 +- .../Rendering/Html/HtmlHelper.cs | 37 ++-- .../Rendering/Html/HtmlHelperOfT.cs | 9 +- .../HtmlHelperValidationExtensions.cs | 169 ++++++++++++++---- .../Rendering/IHtmlHelper.cs | 9 +- .../Rendering/IHtmlHelperOfT.cs | 6 +- src/Microsoft.AspNet.Mvc.Core/ViewContext.cs | 16 ++ 7 files changed, 200 insertions(+), 50 deletions(-) diff --git a/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml b/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml index 9188ca196c..d1b888f97f 100644 --- a/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml +++ b/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml @@ -15,9 +15,9 @@
@Html.ValidationSummary() @Html.ValidationSummary(excludePropertyErrors: true) - @Html.ValidationSummary(message: "Hello from validation message summary 1.") + @Html.ValidationSummary(message: "Hello from validation message summary 1.", tag: "h2") @Html.ValidationSummary(excludePropertyErrors: true, message: "Hello from validation message summary 2") @Html.ValidationSummary(message: "Hello from validation message summary 3", htmlAttributes: new { style = "color: red" }) @Html.ValidationSummary(excludePropertyErrors: true, message: "Hello from validation message summary 4", htmlAttributes: new { style = "color: green" }) - @Html.ValidationSummary(message: "Hello from validation message summary 5", htmlAttributes: new Dictionary { { "style", "color: blue" } }) + @Html.ValidationSummary(message: "Hello from validation message summary 5", htmlAttributes: new Dictionary { { "style", "color: blue" } }, tag: "h1")
\ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index 232ced77a4..9746106e1d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -443,13 +443,16 @@ namespace Microsoft.AspNet.Mvc.Rendering } /// - public HtmlString ValidationMessage(string expression, string message, object htmlAttributes) + public HtmlString ValidationMessage(string expression, string message, object htmlAttributes, string tag) { - return GenerateValidationMessage(expression, message, htmlAttributes); + return GenerateValidationMessage(expression, message, htmlAttributes, tag); } /// - public virtual HtmlString ValidationSummary(bool excludePropertyErrors, string message, IDictionary htmlAttributes) + public virtual HtmlString ValidationSummary(bool excludePropertyErrors, + string message, + IDictionary htmlAttributes, + string tag) { var formContext = ViewContext.ClientValidationEnabled ? ViewContext.FormContext : null; @@ -464,16 +467,20 @@ namespace Microsoft.AspNet.Mvc.Rendering } } - string messageSpan; + string wrappedMessage; if (!string.IsNullOrEmpty(message)) { - var spanTag = new TagBuilder("span"); - spanTag.SetInnerText(message); - messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine; + if (string.IsNullOrEmpty(tag)) + { + tag = ViewContext.ValidationSummaryMessageElement; + } + var messageTag = new TagBuilder(tag); + messageTag.SetInnerText(message); + wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine; } else { - messageSpan = null; + wrappedMessage = null; } var htmlSummary = new StringBuilder(); @@ -516,7 +523,7 @@ namespace Microsoft.AspNet.Mvc.Rendering divBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName); } - divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal); + divBuilder.InnerHtml = wrappedMessage + unorderedList.ToString(TagRenderMode.Normal); if (formContext != null) { @@ -1261,8 +1268,10 @@ namespace Microsoft.AspNet.Mvc.Rendering return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing); } - protected virtual HtmlString GenerateValidationMessage(string expression, string message, - object htmlAttributes) + protected virtual HtmlString GenerateValidationMessage(string expression, + string message, + object htmlAttributes, + string tag) { var modelName = ViewData.TemplateInfo.GetFullHtmlFieldName(expression); if (string.IsNullOrEmpty(modelName)) @@ -1294,7 +1303,11 @@ namespace Microsoft.AspNet.Mvc.Rendering // Even if there are no model errors, we generate the span and add the validation message // if formContext is not null. - var builder = new TagBuilder("span"); + if (string.IsNullOrEmpty(tag)) + { + tag = ViewContext.ValidationMessageElement; + } + var builder = new TagBuilder(tag); builder.MergeAttributes(AnonymousObjectToHtmlAttributes(htmlAttributes)); // Only the style of the span is changed according to the errors if message is null or empty. diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs index 16d88f75eb..0008e5ce29 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs @@ -229,9 +229,14 @@ namespace Microsoft.AspNet.Mvc.Rendering /// public HtmlString ValidationMessageFor([NotNull] Expression> expression, - string message, object htmlAttributes) + string message, + object htmlAttributes, + string tag) { - return GenerateValidationMessage(ExpressionHelper.GetExpressionText(expression), message, htmlAttributes); + return GenerateValidationMessage(ExpressionHelper.GetExpressionText(expression), + message, + htmlAttributes, + tag); } /// diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs index edbcba84ae..0f751bfbc1 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs @@ -12,95 +12,202 @@ namespace Microsoft.AspNet.Mvc.Rendering public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, string expression) { - return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: null); + return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, string message) + string expression, + string message) { - return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null); + return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, object htmlAttributes) + string expression, + object htmlAttributes) { - return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: htmlAttributes); + return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: htmlAttributes, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, string message, object htmlAttributes) + string expression, + string message, + string tag) { - return htmlHelper.ValidationMessage(expression, message, htmlAttributes); + return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null, tag: tag); + } + + public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, + string expression, + string message, + object htmlAttributes) + { + return htmlHelper.ValidationMessage(expression, message, htmlAttributes, tag: null); + } + + public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, + string expression, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationMessage(expression, message, htmlAttributes, tag); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, [NotNull] Expression> expression) { - return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null); + return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, - [NotNull] Expression> expression, string message) + [NotNull] Expression> expression, + string message) { - return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null); + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, - [NotNull] Expression> expression, string message, object htmlAttributes) + [NotNull] Expression> expression, + string message, + object htmlAttributes) { - return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes); + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag: null); + } + + public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, + [NotNull] Expression> expression, + string message, + string tag) + { + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: tag); + } + + public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, + [NotNull] Expression> expression, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: null, + htmlAttributes: null, + tag: null); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors) { - return ValidationSummary(htmlHelper, excludePropertyErrors, message: null); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message: null, + htmlAttributes: null, + tag: null); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, - htmlAttributes: (object)null); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: null, + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: null, + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors, string message) { - return ValidationSummary(htmlHelper, excludePropertyErrors, message, htmlAttributes: (object)null); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + htmlAttributes: null, + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, object htmlAttributes) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, - htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + bool excludePropertyErrors, + string message, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + htmlAttributes: null, + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors, string message, object htmlAttributes) { - return htmlHelper.ValidationSummary(excludePropertyErrors, message, - HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + bool excludePropertyErrors, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, IDictionary htmlAttributes) { - return htmlHelper.ValidationSummary(excludePropertyErrors: false, message: message, - htmlAttributes: htmlAttributes); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: htmlAttributes, + tag: null); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + string message, + IDictionary htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: htmlAttributes, + tag: tag); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs index 3c81a06c39..dd7ef26d2a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs @@ -447,8 +447,10 @@ namespace Microsoft.AspNet.Mvc.Rendering /// An object that contains the HTML attributes to set for the element. /// Alternatively, an instance containing the HTML attributes. /// + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains the validation message - HtmlString ValidationMessage(string modelName, string message, object htmlAttributes); + HtmlString ValidationMessage(string modelName, string message, object htmlAttributes, string tag); /// /// Returns an unordered list (ul element) of validation messages that are in the @@ -458,12 +460,15 @@ namespace Microsoft.AspNet.Mvc.Rendering /// have the summary display all errors. /// The message to display with the validation summary. /// A dictionary that contains the HTML attributes for the element. + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains an unordered list (ul element) of validation messages. /// HtmlString ValidationSummary( bool excludePropertyErrors, string message, - IDictionary htmlAttributes); + IDictionary htmlAttributes, + string tag); /// /// Returns the model value for the given expression . diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs index 1f537dc549..7b934507cd 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs @@ -253,9 +253,13 @@ namespace Microsoft.AspNet.Mvc.Rendering /// An object that contains the HTML attributes to set for the element. /// Alternatively, an /// instance containing the HTML attributes. /// + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains the validation message HtmlString ValidationMessageFor([NotNull] Expression> expression, - string message, object htmlAttributes); + string message, + object htmlAttributes, + string tag); /// /// Returns the model value for the given expression . diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs index 67484b980d..7f3c47ca9d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs @@ -29,6 +29,8 @@ namespace Microsoft.AspNet.Mvc _formContext = _defaultFormContext; UnobtrusiveJavaScriptEnabled = true; ClientValidationEnabled = true; + ValidationSummaryMessageElement = "span"; + ValidationMessageElement = "span"; } public ViewContext( @@ -41,6 +43,8 @@ namespace Microsoft.AspNet.Mvc _formContext = viewContext.FormContext; UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled; ClientValidationEnabled = viewContext.ClientValidationEnabled; + ValidationSummaryMessageElement = viewContext.ValidationSummaryMessageElement; + ValidationMessageElement = viewContext.ValidationMessageElement; View = view; ViewData = viewData; @@ -64,6 +68,18 @@ namespace Microsoft.AspNet.Mvc public bool ClientValidationEnabled { get; set; } + /// + /// Element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationSummaryMessageElement { get; set; } + + /// + /// Element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationMessageElement { get; set; } + public dynamic ViewBag { get