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.
This commit is contained in:
Tian Pan 2014-05-13 20:33:58 -07:00
parent 6082cd9f36
commit a6d89c4482
7 changed files with 200 additions and 50 deletions

View File

@ -15,9 +15,9 @@
<section class="validationSummary"> <section class="validationSummary">
@Html.ValidationSummary() @Html.ValidationSummary()
@Html.ValidationSummary(excludePropertyErrors: true) @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(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(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(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<string, object> { { "style", "color: blue" } }) @Html.ValidationSummary(message: "Hello from validation message summary 5", htmlAttributes: new Dictionary<string, object> { { "style", "color: blue" } }, tag: "h1")
</section> </section>

View File

@ -443,13 +443,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
/// <inheritdoc /> /// <inheritdoc />
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);
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual HtmlString ValidationSummary(bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes) public virtual HtmlString ValidationSummary(bool excludePropertyErrors,
string message,
IDictionary<string, object> htmlAttributes,
string tag)
{ {
var formContext = ViewContext.ClientValidationEnabled ? ViewContext.FormContext : null; var formContext = ViewContext.ClientValidationEnabled ? ViewContext.FormContext : null;
@ -464,16 +467,20 @@ namespace Microsoft.AspNet.Mvc.Rendering
} }
} }
string messageSpan; string wrappedMessage;
if (!string.IsNullOrEmpty(message)) if (!string.IsNullOrEmpty(message))
{ {
var spanTag = new TagBuilder("span"); if (string.IsNullOrEmpty(tag))
spanTag.SetInnerText(message); {
messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine; tag = ViewContext.ValidationSummaryMessageElement;
}
var messageTag = new TagBuilder(tag);
messageTag.SetInnerText(message);
wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
} }
else else
{ {
messageSpan = null; wrappedMessage = null;
} }
var htmlSummary = new StringBuilder(); var htmlSummary = new StringBuilder();
@ -516,7 +523,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
divBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName); divBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName);
} }
divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal); divBuilder.InnerHtml = wrappedMessage + unorderedList.ToString(TagRenderMode.Normal);
if (formContext != null) if (formContext != null)
{ {
@ -1261,8 +1268,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing); return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing);
} }
protected virtual HtmlString GenerateValidationMessage(string expression, string message, protected virtual HtmlString GenerateValidationMessage(string expression,
object htmlAttributes) string message,
object htmlAttributes,
string tag)
{ {
var modelName = ViewData.TemplateInfo.GetFullHtmlFieldName(expression); var modelName = ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
if (string.IsNullOrEmpty(modelName)) 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 // Even if there are no model errors, we generate the span and add the validation message
// if formContext is not null. // 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)); builder.MergeAttributes(AnonymousObjectToHtmlAttributes(htmlAttributes));
// Only the style of the span is changed according to the errors if message is null or empty. // Only the style of the span is changed according to the errors if message is null or empty.

View File

@ -229,9 +229,14 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <inheritdoc /> /// <inheritdoc />
public HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression, public HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> 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);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -12,95 +12,202 @@ namespace Microsoft.AspNet.Mvc.Rendering
public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper,
string expression) 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, 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, 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, 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<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper, public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression) [NotNull] Expression<Func<TModel, TProperty>> expression)
{ {
return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null); return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null, tag: null);
} }
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper, public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression, string message) [NotNull] Expression<Func<TModel, TProperty>> expression,
string message)
{ {
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null); return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: null);
} }
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper, public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression, string message, object htmlAttributes) [NotNull] Expression<Func<TModel, TProperty>> expression,
string message,
object htmlAttributes)
{ {
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes); return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag: null);
}
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression,
string message,
string tag)
{
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: tag);
}
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression,
string message,
object htmlAttributes,
string tag)
{
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag);
} }
public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper) 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) 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) public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message)
{ {
return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, return htmlHelper.ValidationSummary(excludePropertyErrors: false,
htmlAttributes: (object)null); message: message,
htmlAttributes: null,
tag: null);
} }
public static HtmlString ValidationSummary( public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, string tag)
[NotNull] this IHtmlHelper htmlHelper, {
return htmlHelper.ValidationSummary(excludePropertyErrors: false,
message: message,
htmlAttributes: null,
tag: tag);
}
public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper,
bool excludePropertyErrors, bool excludePropertyErrors,
string message) string message)
{ {
return ValidationSummary(htmlHelper, excludePropertyErrors, message, htmlAttributes: (object)null); return htmlHelper.ValidationSummary(excludePropertyErrors,
message,
htmlAttributes: null,
tag: null);
} }
public static HtmlString ValidationSummary( public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper,
[NotNull] this IHtmlHelper htmlHelper,
string message, string message,
object htmlAttributes) object htmlAttributes)
{ {
return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, return htmlHelper.ValidationSummary(excludePropertyErrors: false,
htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); message: message,
htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes),
tag: null);
} }
public static HtmlString ValidationSummary( public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper,
[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, bool excludePropertyErrors,
string message, string message,
object htmlAttributes) object htmlAttributes)
{ {
return htmlHelper.ValidationSummary(excludePropertyErrors, message, return htmlHelper.ValidationSummary(excludePropertyErrors,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); message,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes),
tag: null);
} }
public static HtmlString ValidationSummary( public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper,
[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, string message,
IDictionary<string, object> htmlAttributes) IDictionary<string, object> htmlAttributes)
{ {
return htmlHelper.ValidationSummary(excludePropertyErrors: false, message: message, return htmlHelper.ValidationSummary(excludePropertyErrors: false,
htmlAttributes: htmlAttributes); message: message,
htmlAttributes: htmlAttributes,
tag: null);
}
public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper,
string message,
IDictionary<string, object> htmlAttributes,
string tag)
{
return htmlHelper.ValidationSummary(excludePropertyErrors: false,
message: message,
htmlAttributes: htmlAttributes,
tag: tag);
} }
} }
} }

View File

@ -447,8 +447,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element. /// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes. /// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param> /// </param>
/// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML.
/// Its default value is <see cref="ViewContext.ValidationMessageElement" />.</param>
/// <returns>An <see cref="HtmlString"/> that contains the validation message</returns> /// <returns>An <see cref="HtmlString"/> that contains the validation message</returns>
HtmlString ValidationMessage(string modelName, string message, object htmlAttributes); HtmlString ValidationMessage(string modelName, string message, object htmlAttributes, string tag);
/// <summary> /// <summary>
/// Returns an unordered list (ul element) of validation messages that are in the /// 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.</param> /// have the summary display all errors.</param>
/// <param name="message">The message to display with the validation summary.</param> /// <param name="message">The message to display with the validation summary.</param>
/// <param name="htmlAttributes">A dictionary that contains the HTML attributes for the element.</param> /// <param name="htmlAttributes">A dictionary that contains the HTML attributes for the element.</param>
/// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML.
/// Its default value is <see cref="ViewContext.ValidationMessageElement" />.</param>
/// <returns>An <see cref="HtmlString"/> that contains an unordered list (ul element) of validation messages. /// <returns>An <see cref="HtmlString"/> that contains an unordered list (ul element) of validation messages.
/// </returns> /// </returns>
HtmlString ValidationSummary( HtmlString ValidationSummary(
bool excludePropertyErrors, bool excludePropertyErrors,
string message, string message,
IDictionary<string, object> htmlAttributes); IDictionary<string, object> htmlAttributes,
string tag);
/// <summary> /// <summary>
/// Returns the model value for the given expression <paramref name="name"/>. /// Returns the model value for the given expression <paramref name="name"/>.

View File

@ -253,9 +253,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element. /// <param name="htmlAttributes"> An object that contains the HTML attributes to set for the element.
/// Alternatively, an /// <see cref="IDictionary{string, object}"/> instance containing the HTML attributes. /// Alternatively, an /// <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param> /// </param>
/// <param name="tag">The tag to wrap the <paramref name="message"/> in the generated HTML.
/// Its default value is <see cref="ViewContext.ValidationMessageElement" />.</param>
/// <returns>An <see cref="HtmlString"/> that contains the validation message</returns> /// <returns>An <see cref="HtmlString"/> that contains the validation message</returns>
HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression, HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
string message, object htmlAttributes); string message,
object htmlAttributes,
string tag);
/// <summary> /// <summary>
/// Returns the model value for the given expression <paramref name="expression"/>. /// Returns the model value for the given expression <paramref name="expression"/>.

View File

@ -29,6 +29,8 @@ namespace Microsoft.AspNet.Mvc
_formContext = _defaultFormContext; _formContext = _defaultFormContext;
UnobtrusiveJavaScriptEnabled = true; UnobtrusiveJavaScriptEnabled = true;
ClientValidationEnabled = true; ClientValidationEnabled = true;
ValidationSummaryMessageElement = "span";
ValidationMessageElement = "span";
} }
public ViewContext( public ViewContext(
@ -41,6 +43,8 @@ namespace Microsoft.AspNet.Mvc
_formContext = viewContext.FormContext; _formContext = viewContext.FormContext;
UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled; UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled;
ClientValidationEnabled = viewContext.ClientValidationEnabled; ClientValidationEnabled = viewContext.ClientValidationEnabled;
ValidationSummaryMessageElement = viewContext.ValidationSummaryMessageElement;
ValidationMessageElement = viewContext.ValidationMessageElement;
View = view; View = view;
ViewData = viewData; ViewData = viewData;
@ -64,6 +68,18 @@ namespace Microsoft.AspNet.Mvc
public bool ClientValidationEnabled { get; set; } public bool ClientValidationEnabled { get; set; }
/// <summary>
/// Element name used to wrap a top-level message generated by
/// <see cref="HtmlHelperValidationExtensions.ValidationSummary(IHtmlHelper)"/> and other overloads.
/// </summary>
public string ValidationSummaryMessageElement { get; set; }
/// <summary>
/// Element name used to wrap a top-level message generated by
/// <see cref="HtmlHelperValidationExtensions.ValidationMessage(IHtmlHelper, string)"/> and other overloads.
/// </summary>
public string ValidationMessageElement { get; set; }
public dynamic ViewBag public dynamic ViewBag
{ {
get get