WebFX 98 - Adding GetValidationAttributes support
This commit is contained in:
parent
bbafa0a29a
commit
3b7983181d
|
|
@ -197,6 +197,7 @@
|
|||
<Compile Include="Rendering\SelectList.cs" />
|
||||
<Compile Include="Rendering\SelectListGroup.cs" />
|
||||
<Compile Include="Rendering\SelectListItem.cs" />
|
||||
<Compile Include="Rendering\UnobtrusiveValidationAttributesGenerator.cs" />
|
||||
<Compile Include="Rendering\ViewEngineResult.cs" />
|
||||
<Compile Include="RouteConstraintAttribute.cs" />
|
||||
<Compile Include="RouteDataActionConstraint.cs" />
|
||||
|
|
|
|||
|
|
@ -939,6 +939,86 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("FilterFactoryAttribute_TypeMustImplementIFilter"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: {0}
|
||||
/// </summary>
|
||||
internal static string UnobtrusiveJavascript_ValidationParameterCannotBeEmpty
|
||||
{
|
||||
get { return GetString("UnobtrusiveJavascript_ValidationParameterCannotBeEmpty"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: {0}
|
||||
/// </summary>
|
||||
internal static string FormatUnobtrusiveJavascript_ValidationParameterCannotBeEmpty(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnobtrusiveJavascript_ValidationParameterCannotBeEmpty"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: {0}, client rule type: {1}
|
||||
/// </summary>
|
||||
internal static string UnobtrusiveJavascript_ValidationParameterMustBeLegal
|
||||
{
|
||||
get { return GetString("UnobtrusiveJavascript_ValidationParameterMustBeLegal"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: {0}, client rule type: {1}
|
||||
/// </summary>
|
||||
internal static string FormatUnobtrusiveJavascript_ValidationParameterMustBeLegal(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnobtrusiveJavascript_ValidationParameterMustBeLegal"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: {0}
|
||||
/// </summary>
|
||||
internal static string UnobtrusiveJavascript_ValidationTypeCannotBeEmpty
|
||||
{
|
||||
get { return GetString("UnobtrusiveJavascript_ValidationTypeCannotBeEmpty"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: {0}
|
||||
/// </summary>
|
||||
internal static string FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnobtrusiveJavascript_ValidationTypeCannotBeEmpty"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: "{0}", client rule type: {1}
|
||||
/// </summary>
|
||||
internal static string UnobtrusiveJavascript_ValidationTypeMustBeLegal
|
||||
{
|
||||
get { return GetString("UnobtrusiveJavascript_ValidationTypeMustBeLegal"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: "{0}", client rule type: {1}
|
||||
/// </summary>
|
||||
internal static string FormatUnobtrusiveJavascript_ValidationTypeMustBeLegal(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnobtrusiveJavascript_ValidationTypeMustBeLegal"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: {0}
|
||||
/// </summary>
|
||||
internal static string UnobtrusiveJavascript_ValidationTypeMustBeUnique
|
||||
{
|
||||
get { return GetString("UnobtrusiveJavascript_ValidationTypeMustBeUnique"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: {0}
|
||||
/// </summary>
|
||||
internal static string FormatUnobtrusiveJavascript_ValidationTypeMustBeUnique(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("UnobtrusiveJavascript_ValidationTypeMustBeUnique"), p0);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
private readonly IUrlHelper _urlHelper;
|
||||
private readonly IViewEngine _viewEngine;
|
||||
private readonly AntiForgery _antiForgeryInstance;
|
||||
private readonly IActionBindingContextProvider _actionBindingContextProvider;
|
||||
|
||||
private ViewContext _viewContext;
|
||||
|
||||
|
|
@ -57,13 +58,15 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
public HtmlHelper(
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] AntiForgery antiForgeryInstance)
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] AntiForgery antiForgeryInstance,
|
||||
[NotNull] IActionBindingContextProvider actionBindingContextProvider)
|
||||
{
|
||||
_viewEngine = viewEngine;
|
||||
MetadataProvider = metadataProvider;
|
||||
_urlHelper = urlHelper;
|
||||
_antiForgeryInstance = antiForgeryInstance;
|
||||
_actionBindingContextProvider = actionBindingContextProvider;
|
||||
|
||||
// Underscores are fine characters in id's.
|
||||
IdAttributeDotReplacement = "_";
|
||||
|
|
@ -640,8 +643,21 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
// then we can't render the attributes (we'd have no <form> to attach them to).
|
||||
protected IDictionary<string, object> GetValidationAttributes(string name, ModelMetadata metadata)
|
||||
{
|
||||
// TODO: Add validation attributes to input helpers.
|
||||
return new Dictionary<string, object>();
|
||||
var formContext = ViewContext.GetFormContextForClientValidation();
|
||||
if (!ViewContext.UnobtrusiveJavaScriptEnabled || formContext == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
|
||||
if (formContext.RenderedField(fullName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
formContext.RenderedField(fullName, true);
|
||||
var clientRules = GetClientValidationRules(name, metadata);
|
||||
return UnobtrusiveValidationAttributesGenerator.GetValidationAttributes(clientRules);
|
||||
}
|
||||
|
||||
protected virtual HtmlString GenerateCheckBox(ModelMetadata metadata, string name, bool? isChecked,
|
||||
|
|
@ -1350,6 +1366,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return new HtmlString(Encode(resolvedValue));
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(string name, ModelMetadata metadata)
|
||||
{
|
||||
var actionBindingContext = _actionBindingContextProvider.GetActionBindingContextAsync(ViewContext).Result;
|
||||
metadata = metadata ??
|
||||
ExpressionMetadataProvider.FromStringExpression(name, ViewData, MetadataProvider);
|
||||
return actionBindingContext.ValidatorProviders
|
||||
.SelectMany(vp => vp.GetValidators(metadata))
|
||||
.OfType<IClientModelValidator>()
|
||||
.SelectMany(v => v.GetClientValidationRules(
|
||||
new ClientModelValidationContext(metadata, MetadataProvider)));
|
||||
}
|
||||
|
||||
private static string GetInputTypeString(InputType inputType)
|
||||
{
|
||||
switch (inputType)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper,
|
||||
[NotNull] AntiForgery antiForgeryInstance)
|
||||
: base(viewEngine, metadataProvider, urlHelper, antiForgeryInstance)
|
||||
[NotNull] AntiForgery antiForgeryInstance,
|
||||
[NotNull] IActionBindingContextProvider actionBindingContextProvider)
|
||||
: base(viewEngine, metadataProvider, urlHelper, antiForgeryInstance, actionBindingContextProvider)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Rendering
|
||||
{
|
||||
public static class UnobtrusiveValidationAttributesGenerator
|
||||
{
|
||||
public static IDictionary<string, object> GetValidationAttributes(
|
||||
[NotNull] IEnumerable<ModelClientValidationRule> clientRules)
|
||||
{
|
||||
IDictionary<string, object> results = null;
|
||||
|
||||
foreach (var rule in clientRules)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
results = new Dictionary<string, object>(StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
var ruleName = "data-val-" + rule.ValidationType;
|
||||
|
||||
ValidateUnobtrusiveValidationRule(rule, results, ruleName);
|
||||
|
||||
results.Add(ruleName, rule.ErrorMessage ?? string.Empty);
|
||||
ruleName += "-";
|
||||
|
||||
foreach (var kvp in rule.ValidationParameters)
|
||||
{
|
||||
results.Add(ruleName + kvp.Key, kvp.Value ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
if (results != null)
|
||||
{
|
||||
results.Add("data-val", "true");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void ValidateUnobtrusiveValidationRule(ModelClientValidationRule rule,
|
||||
IDictionary<string, object> resultsDictionary, string dictionaryKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(rule.ValidationType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationTypeCannotBeEmpty(rule.GetType().FullName), "rule");
|
||||
}
|
||||
|
||||
if (resultsDictionary.ContainsKey(dictionaryKey))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationTypeMustBeUnique(rule.ValidationType));
|
||||
}
|
||||
|
||||
if (!rule.ValidationType.All(char.IsLower))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationTypeMustBeLegal(
|
||||
rule.ValidationType,
|
||||
rule.GetType().FullName));
|
||||
}
|
||||
|
||||
foreach (var key in rule.ValidationParameters.Keys)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationParameterCannotBeEmpty(rule.GetType().FullName));
|
||||
}
|
||||
|
||||
if (!char.IsLower(key[0]) || key.Any(c => !char.IsLower(c) && !char.IsDigit(c)))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
Resources.FormatUnobtrusiveJavascript_ValidationParameterMustBeLegal(
|
||||
key,
|
||||
rule.GetType().FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -288,4 +288,19 @@
|
|||
<data name="FilterFactoryAttribute_TypeMustImplementIFilter" xml:space="preserve">
|
||||
<value>The type provided to '{0}' must implement '{1}'.</value>
|
||||
</data>
|
||||
</root>
|
||||
<data name="UnobtrusiveJavascript_ValidationParameterCannotBeEmpty" xml:space="preserve">
|
||||
<value>Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: {0}</value>
|
||||
</data>
|
||||
<data name="UnobtrusiveJavascript_ValidationParameterMustBeLegal" xml:space="preserve">
|
||||
<value>Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: {0}, client rule type: {1}</value>
|
||||
</data>
|
||||
<data name="UnobtrusiveJavascript_ValidationTypeCannotBeEmpty" xml:space="preserve">
|
||||
<value>Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: {0}</value>
|
||||
</data>
|
||||
<data name="UnobtrusiveJavascript_ValidationTypeMustBeLegal" xml:space="preserve">
|
||||
<value>Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: "{0}", client rule type: {1}</value>
|
||||
</data>
|
||||
<data name="UnobtrusiveJavascript_ValidationTypeMustBeUnique" xml:space="preserve">
|
||||
<value>Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: {0}</value>
|
||||
</data>
|
||||
</root>
|
||||
Loading…
Reference in New Issue