Adding an appropriate sample to use ValidationMessage and ValidationMessageFor.
This commit is contained in:
parent
f17d444b8a
commit
185ad31491
|
|
@ -8,6 +8,7 @@ namespace MvcSample.Web.Models
|
|||
[MinLength(4)]
|
||||
public string Name { get; set; }
|
||||
public string Address { get; set; }
|
||||
[Range(27, 70)]
|
||||
public int Age { get; set; }
|
||||
public decimal GPA { get; set; }
|
||||
public User Dependent { get; set; }
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@
|
|||
<td>
|
||||
@Html.TextBox("Name")
|
||||
</td>
|
||||
<td>
|
||||
@Html.ValidationMessage("Name.Name", "Name is required", new { @style = "font-weight: bold" })
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
|
@ -66,6 +69,9 @@
|
|||
<td>
|
||||
@Html.DropDownListFor(model => model.Age, (IEnumerable<SelectListItem>)ViewBag.Ages, htmlAttributes: new { @class = "form-control" })
|
||||
</td>
|
||||
<td>
|
||||
@Html.ValidationMessageFor(model => model.Age, "Age must be between 27 and 70", new { @style = "font-weight: bold" })
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -416,6 +416,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return new HtmlString(value == null ? null : value.ToString());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public HtmlString ValidationMessage(string expression, string message, object htmlAttributes)
|
||||
{
|
||||
return GenerateValidationMessage(expression, message, htmlAttributes);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual HtmlString ValidationSummary(bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
|
|
@ -508,46 +514,6 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return divBuilder.ToHtmlString(TagRenderMode.Normal);
|
||||
}
|
||||
|
||||
public HtmlString ValidationMessage(string name, string message, object htmlAttributes)
|
||||
{
|
||||
ModelState modelState;
|
||||
ViewData.ModelState.TryGetValue(name, out modelState);
|
||||
|
||||
ModelErrorCollection errors = null;
|
||||
if (modelState != null)
|
||||
{
|
||||
errors = modelState.Errors;
|
||||
}
|
||||
|
||||
bool hasError = errors != null && errors.Any();
|
||||
if (!hasError && !ViewContext.UnobtrusiveJavaScriptEnabled)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = null;
|
||||
if (hasError)
|
||||
{
|
||||
error = message ?? errors.First().ErrorMessage;
|
||||
}
|
||||
|
||||
var tagBuilder = new TagBuilder("span") { InnerHtml = Encode(error) };
|
||||
tagBuilder.MergeAttributes(AnonymousObjectToHtmlAttributes(htmlAttributes));
|
||||
|
||||
if (ViewContext.UnobtrusiveJavaScriptEnabled)
|
||||
{
|
||||
bool replaceValidationMessageContents = string.IsNullOrEmpty(message);
|
||||
tagBuilder.MergeAttribute("data-valmsg-for", name);
|
||||
tagBuilder.MergeAttribute("data-valmsg-replace",
|
||||
replaceValidationMessageContents.ToString().ToLowerInvariant());
|
||||
}
|
||||
|
||||
tagBuilder.AddCssClass(hasError ? ValidationMessageCssClassName : ValidationMessageValidCssClassName);
|
||||
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the HTTP method that handles form input (GET or POST) as a string.
|
||||
/// </summary>
|
||||
|
|
@ -698,7 +664,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
var resolvedDisplayName = metadata.PropertyName;
|
||||
if (resolvedDisplayName == null)
|
||||
{
|
||||
resolvedDisplayName = string.IsNullOrEmpty(htmlFieldName) ?
|
||||
resolvedDisplayName = string.IsNullOrEmpty(htmlFieldName) ?
|
||||
string.Empty :
|
||||
htmlFieldName.Split('.').Last();
|
||||
}
|
||||
|
|
@ -823,7 +789,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return new HtmlString(Encode(ViewData.TemplateInfo.GetFullHtmlFieldName(expression)));
|
||||
}
|
||||
|
||||
protected virtual HtmlString GenerateLabel([NotNull] ModelMetadata metadata,
|
||||
protected virtual HtmlString GenerateLabel([NotNull] ModelMetadata metadata,
|
||||
string htmlFieldName,
|
||||
string labelText,
|
||||
object htmlAttributes)
|
||||
|
|
@ -832,7 +798,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
string resolvedLabelText = labelText ?? metadata.PropertyName;
|
||||
if (resolvedLabelText == null)
|
||||
{
|
||||
resolvedLabelText = string.IsNullOrEmpty(htmlFieldName) ?
|
||||
resolvedLabelText = string.IsNullOrEmpty(htmlFieldName) ?
|
||||
string.Empty :
|
||||
htmlFieldName.Split('.').Last();
|
||||
}
|
||||
|
|
@ -1220,6 +1186,76 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing);
|
||||
}
|
||||
|
||||
protected virtual HtmlString GenerateValidationMessage(string expression, string message,
|
||||
object htmlAttributes)
|
||||
{
|
||||
var modelName = ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
|
||||
if (string.IsNullOrEmpty(modelName))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "expression");
|
||||
}
|
||||
|
||||
var formContext = ViewContext.GetFormContextForClientValidation();
|
||||
|
||||
if (!ViewData.ModelState.ContainsKey(modelName) && formContext == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ModelState modelState;
|
||||
var tryGetModelStateResult = ViewData.ModelState.TryGetValue(modelName, 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.
|
||||
var builder = new TagBuilder("span");
|
||||
builder.MergeAttributes(AnonymousObjectToHtmlAttributes(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.
|
||||
builder.AddCssClass((modelError != null) ?
|
||||
ValidationMessageCssClassName :
|
||||
ValidationMessageValidCssClassName);
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
builder.SetInnerText(message);
|
||||
}
|
||||
else if (modelError != null)
|
||||
{
|
||||
builder.SetInnerText(ValidationHelpers.GetUserErrorMessageOrDefault(modelError, modelState));
|
||||
}
|
||||
|
||||
if (formContext != null)
|
||||
{
|
||||
var replaceValidationMessageContents = string.IsNullOrEmpty(message);
|
||||
|
||||
if (ViewContext.UnobtrusiveJavaScriptEnabled)
|
||||
{
|
||||
builder.MergeAttribute("data-valmsg-for", modelName);
|
||||
builder.MergeAttribute("data-valmsg-replace",
|
||||
replaceValidationMessageContents.ToString().ToLowerInvariant());
|
||||
}
|
||||
|
||||
// TODO: (WebFX-217) Add support for Unobtrusive JS disabled -
|
||||
// Modify the field metadata to add the validation message,
|
||||
// Add the client validation id in the field metadata
|
||||
}
|
||||
|
||||
return builder.ToHtmlString(TagRenderMode.Normal);
|
||||
}
|
||||
|
||||
protected virtual HtmlString GenerateValue(string name, object value, string format, bool useViewData)
|
||||
{
|
||||
var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
/// Initializes a new instance of the <see cref="HtmlHelper{TModel}"/> class.
|
||||
/// </summary>
|
||||
public HtmlHelper(
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] AntiForgery antiForgeryInstance)
|
||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public new ViewDataDictionary<TModel> ViewData { get; private set;}
|
||||
public new ViewDataDictionary<TModel> ViewData { get; private set; }
|
||||
|
||||
public override void Contextualize([NotNull] ViewContext viewContext)
|
||||
{
|
||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
{
|
||||
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
|
||||
"ViewData",
|
||||
typeof(ViewContext)),
|
||||
typeof(ViewContext)),
|
||||
"viewContext");
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
object additionalViewData)
|
||||
{
|
||||
var metadata = ExpressionMetadataProvider.FromLambdaExpression(expression,
|
||||
ViewData,
|
||||
ViewData,
|
||||
MetadataProvider);
|
||||
|
||||
return GenerateDisplay(metadata,
|
||||
|
|
@ -212,7 +212,14 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public HtmlString ValueFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression, string format)
|
||||
public HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
|
||||
string message, object htmlAttributes)
|
||||
{
|
||||
return GenerateValidationMessage(ExpressionHelper.GetExpressionText(expression), message, htmlAttributes);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public HtmlString ValueFor<TProperty>(Expression<Func<TModel, TProperty>> expression, string format)
|
||||
{
|
||||
var metadata = GetModelMetadata(expression);
|
||||
return GenerateValue(ExpressionHelper.GetExpressionText(expression), metadata.Model, format,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Rendering
|
||||
{
|
||||
public static class HtmlHelperValidationExtensions
|
||||
{
|
||||
public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper,
|
||||
string expression)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper,
|
||||
string expression, string message)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper,
|
||||
string expression, object htmlAttributes)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper,
|
||||
string expression, string message, object htmlAttributes)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(expression, message, htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
[NotNull] Expression<Func<TModel, TProperty>> expression)
|
||||
{
|
||||
return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
[NotNull] Expression<Func<TModel, TProperty>> expression, string message)
|
||||
{
|
||||
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessageFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
[NotNull] Expression<Func<TModel, TProperty>> expression, string message, object htmlAttributes)
|
||||
{
|
||||
return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper)
|
||||
{
|
||||
return ValidationSummary(htmlHelper, excludePropertyErrors: false);
|
||||
|
|
@ -55,41 +99,5 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return htmlHelper.ValidationSummary(excludePropertyErrors: false, message: message,
|
||||
htmlAttributes: htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName)
|
||||
{
|
||||
return ValidationMessage(htmlHelper, modelName, message: null, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName, string message)
|
||||
{
|
||||
return ValidationMessage(htmlHelper, modelName, message, htmlAttributes: null);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName, object htmlAttributes)
|
||||
{
|
||||
return ValidationMessage(htmlHelper, modelName, message: null, htmlAttributes: htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
return ValidationMessage(htmlHelper, modelName, message: null, htmlAttributes: htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName, string message, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(modelName, message, htmlAttributes);
|
||||
}
|
||||
|
||||
public static HtmlString ValidationMessage<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
|
||||
string modelName, string message, object htmlAttributes)
|
||||
{
|
||||
return htmlHelper.ValidationMessage(modelName, message, htmlAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,6 +393,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
|
||||
HtmlString TextBox(string name, object value, string format, IDictionary<string, object> htmlAttributes);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the validation message if an error exists in the <see cref="ModelStateDictionary"/> object.
|
||||
/// </summary>
|
||||
/// <param name="modelName">The name of the property that is being validated.</param>
|
||||
/// <param name="message">The message to be displayed. This will always be visible but client-side
|
||||
/// validation may update the associated CSS class.</param>
|
||||
/// <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.
|
||||
/// </param>
|
||||
/// <returns>An <see cref="HtmlString"/> that contains the validation message</returns>
|
||||
HtmlString ValidationMessage(string modelName, string message, object htmlAttributes);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an unordered list (ul element) of validation messages that are in the
|
||||
/// <see cref="ModelStateDictionary"/> object.
|
||||
|
|
|
|||
|
|
@ -224,14 +224,17 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
IDictionary<string, object> htmlAttributes);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the validation message if an error exists in the <see cref="ModelStateDictionary"/> object.
|
||||
/// Returns the validation message for the specified expression
|
||||
/// </summary>
|
||||
/// <param name="modelName">The name of the property that is being validated.</param>
|
||||
/// <param name="message">The message to be displayed if the specified field contains an error.</param>
|
||||
/// <param name="htmlAttributes">Dictionary that contains the HTML attributes which should
|
||||
/// be applied on the element</param>
|
||||
/// <returns></returns>
|
||||
HtmlString ValidationMessage(string modelName, string message, object htmlAttributes);
|
||||
/// <param name="expression">An expression, relative to the current model.</param>
|
||||
/// <param name="message">The message to be displayed. This will always be visible but client-side
|
||||
/// validation may update the associated CSS class.</param>
|
||||
/// <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.
|
||||
/// </param>
|
||||
/// <returns>An <see cref="HtmlString"/> that contains the validation message</returns>
|
||||
HtmlString ValidationMessageFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
|
||||
string message, object htmlAttributes);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the model value for the given expression <paramref name="expression"/>.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
|
|
@ -82,5 +79,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
public ViewDataDictionary ViewData { get; set; }
|
||||
|
||||
public TextWriter Writer { get; set; }
|
||||
|
||||
public FormContext GetFormContextForClientValidation()
|
||||
{
|
||||
return (ClientValidationEnabled) ? FormContext : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue