Reviving RangeAttributeAdapter, RequiredAttributeAdapter,
StringLengthAttributeAdapter * Adding remaining DataTypeAttribute adapter rules
This commit is contained in:
parent
a5afd3eb42
commit
f740aabb79
|
|
@ -71,6 +71,9 @@
|
|||
<Compile Include="RequestContext.cs" />
|
||||
<Compile Include="Validation\AssociatedValidatorProvider.cs" />
|
||||
<Compile Include="Validation\ClientModelValidationContext.cs" />
|
||||
<Compile Include="Validation\RequiredAttributeAdapter.cs" />
|
||||
<Compile Include="Validation\StringLengthAttributeAdapter.cs" />
|
||||
<Compile Include="Validation\RangeAttributeAdapter.cs" />
|
||||
<Compile Include="Validation\CompareAttributeAdapter.cs" />
|
||||
<Compile Include="Validation\CompositeModelValidator.cs" />
|
||||
<Compile Include="Validation\DataAnnotationsModelValidator.cs" />
|
||||
|
|
@ -89,8 +92,11 @@
|
|||
<Compile Include="Validation\ModelClientValidationEqualToRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationMaxLengthRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationMinLengthRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationRangeRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationRegexRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationRequiredRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationRule.cs" />
|
||||
<Compile Include="Validation\ModelClientValidationStringLengthRule.cs" />
|
||||
<Compile Include="Validation\ModelValidatedEventArgs.cs" />
|
||||
<Compile Include="Validation\ModelValidatingEventArgs.cs" />
|
||||
<Compile Include="Validation\ModelValidationContext.cs" />
|
||||
|
|
|
|||
|
|
@ -86,6 +86,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
AddValidationAttributeAdapter(dict, typeof(CompareAttribute),
|
||||
(attribute) => new CompareAttributeAdapter((CompareAttribute)attribute));
|
||||
|
||||
AddValidationAttributeAdapter(dict, typeof(RequiredAttribute),
|
||||
(attribute) => new RequiredAttributeAdapter((RequiredAttribute)attribute));
|
||||
|
||||
AddValidationAttributeAdapter(dict, typeof(RangeAttribute),
|
||||
(attribute) => new RangeAttributeAdapter((RangeAttribute)attribute));
|
||||
|
||||
AddValidationAttributeAdapter(dict, typeof(StringLengthAttribute),
|
||||
(attribute) => new StringLengthAttributeAdapter((StringLengthAttribute)attribute));
|
||||
|
||||
AddDataTypeAttributeAdapter(dict, typeof(CreditCardAttribute), "creditcard");
|
||||
AddDataTypeAttributeAdapter(dict, typeof(EmailAddressAttribute), "email");
|
||||
AddDataTypeAttributeAdapter(dict, typeof(PhoneAttribute), "phone");
|
||||
AddDataTypeAttributeAdapter(dict, typeof(UrlAttribute), "url");
|
||||
|
||||
return dict;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class ModelClientValidationRangeRule : ModelClientValidationRule
|
||||
{
|
||||
private const string RangeValidationType = "range";
|
||||
private const string MinValidationParameter = "min";
|
||||
private const string MaxValidationParameter = "max";
|
||||
|
||||
public ModelClientValidationRangeRule([NotNull] string errorMessage,
|
||||
[NotNull] object minValue,
|
||||
[NotNull] object maxValue)
|
||||
: base(RangeValidationType, errorMessage)
|
||||
{
|
||||
ValidationParameters[MinValidationParameter] = minValue;
|
||||
ValidationParameters[MaxValidationParameter] = maxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class ModelClientValidationRequiredRule : ModelClientValidationRule
|
||||
{
|
||||
private const string RequiredValidationType = "required";
|
||||
|
||||
public ModelClientValidationRequiredRule(string errorMessage) :
|
||||
base(RequiredValidationType, errorMessage)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class ModelClientValidationStringLengthRule : ModelClientValidationRule
|
||||
{
|
||||
private const string LengthValidationType = "length";
|
||||
private const string MinValidationParameter = "min";
|
||||
private const string MaxValidationParameter = "max";
|
||||
|
||||
public ModelClientValidationStringLengthRule(string errorMessage, int minimumLength, int maximumLength)
|
||||
: base(LengthValidationType, errorMessage)
|
||||
{
|
||||
if (minimumLength != 0)
|
||||
{
|
||||
ValidationParameters[MinValidationParameter] = minimumLength;
|
||||
}
|
||||
|
||||
if (maximumLength != int.MaxValue)
|
||||
{
|
||||
ValidationParameters[MaxValidationParameter] = maximumLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class RangeAttributeAdapter : DataAnnotationsModelValidator<RangeAttribute>
|
||||
{
|
||||
public RangeAttributeAdapter(RangeAttribute attribute)
|
||||
: base(attribute)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(
|
||||
[NotNull] ClientModelValidationContext context)
|
||||
{
|
||||
var errorMessage = GetErrorMessage(context.ModelMetadata);
|
||||
return new[] { new ModelClientValidationRangeRule(errorMessage, Attribute.Minimum, Attribute.Maximum) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
|
||||
{
|
||||
public RequiredAttributeAdapter(RequiredAttribute attribute)
|
||||
: base(attribute)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(
|
||||
[NotNull] ClientModelValidationContext context)
|
||||
{
|
||||
var errorMessage = GetErrorMessage(context.ModelMetadata);
|
||||
return new[] { new ModelClientValidationRequiredRule(errorMessage) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class StringLengthAttributeAdapter : DataAnnotationsModelValidator<StringLengthAttribute>
|
||||
{
|
||||
public StringLengthAttributeAdapter(StringLengthAttribute attribute)
|
||||
: base(attribute)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(
|
||||
[NotNull] ClientModelValidationContext context)
|
||||
{
|
||||
var errorMessage = GetErrorMessage(context.ModelMetadata);
|
||||
return new[] { new ModelClientValidationStringLengthRule(errorMessage,
|
||||
Attribute.MinimumLength,
|
||||
Attribute.MaximumLength) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,9 @@
|
|||
<Compile Include="ModelBindingContextTest.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs" />
|
||||
<Compile Include="Utils\SimpleHttpValueProvider.cs" />
|
||||
<Compile Include="Validation\RequiredAttributeAdapterTest.cs" />
|
||||
<Compile Include="Validation\StringLengthAttributeAdapterTest.cs" />
|
||||
<Compile Include="Validation\RangeAttributeAdapterTest.cs" />
|
||||
<Compile Include="Validation\AssociatedValidatorProviderTest.cs" />
|
||||
<Compile Include="Validation\CompareAttributeTest.cs" />
|
||||
<Compile Include="Validation\DataAnnotationsModelValidatorProviderTest.cs" />
|
||||
|
|
|
|||
|
|
@ -13,51 +13,74 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
private readonly DataAnnotationsModelMetadataProvider _metadataProvider = new DataAnnotationsModelMetadataProvider();
|
||||
|
||||
public static IEnumerable<object[]> KnownAdapterTypeData
|
||||
public static IEnumerable<object[]> DataAnnotationAdapters
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { typeof(RegularExpressionAttribute),
|
||||
new RegularExpressionAttribute("abc"),
|
||||
typeof(RegularExpressionAttributeAdapter), null };
|
||||
yield return new object[] { new RegularExpressionAttribute("abc"),
|
||||
typeof(RegularExpressionAttributeAdapter) };
|
||||
|
||||
yield return new object[] { typeof(MaxLengthAttribute),
|
||||
new MaxLengthAttribute(),
|
||||
typeof(MaxLengthAttributeAdapter), null };
|
||||
yield return new object[] { new MaxLengthAttribute(),
|
||||
typeof(MaxLengthAttributeAdapter) };
|
||||
|
||||
yield return new object[] { typeof(MinLengthAttribute),
|
||||
new MinLengthAttribute(1),
|
||||
typeof(MinLengthAttributeAdapter), null };
|
||||
yield return new object[] { new MinLengthAttribute(1),
|
||||
typeof(MinLengthAttributeAdapter) };
|
||||
|
||||
yield return new object[] { typeof(UrlAttribute),
|
||||
new UrlAttribute(),
|
||||
typeof(DataTypeAttributeAdapter), "url" };
|
||||
yield return new object[] { new RangeAttribute(1, 100),
|
||||
typeof(RangeAttributeAdapter) };
|
||||
|
||||
yield return new object[] { new StringLengthAttribute(6),
|
||||
typeof(StringLengthAttributeAdapter) };
|
||||
|
||||
yield return new object[] { new RequiredAttribute(),
|
||||
typeof(RequiredAttributeAdapter) };
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("KnownAdapterTypeData")]
|
||||
public void AdapterForKnownTypeRegistered(Type attributeType,
|
||||
ValidationAttribute validationAttr,
|
||||
Type expectedAdapterType,
|
||||
string expectedRuleName)
|
||||
[MemberData("DataAnnotationAdapters")]
|
||||
public void AdapterFactory_RegistersAdapters_ForDataAnnotationAttributes(ValidationAttribute attribute,
|
||||
Type expectedAdapterType)
|
||||
{
|
||||
// Arrange
|
||||
var adapters = new DataAnnotationsModelValidatorProvider().AttributeFactories;
|
||||
var adapterFactory = adapters.Single(kvp => kvp.Key == attributeType).Value;
|
||||
var adapterFactory = adapters.Single(kvp => kvp.Key == attribute.GetType()).Value;
|
||||
|
||||
// Act
|
||||
var adapter = adapterFactory(validationAttr);
|
||||
var adapter = adapterFactory(attribute);
|
||||
|
||||
// Assert
|
||||
Assert.IsType(expectedAdapterType, adapter);
|
||||
if (expectedRuleName != null)
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> DataTypeAdapters
|
||||
{
|
||||
get
|
||||
{
|
||||
var dataTypeAdapter = Assert.IsType<DataTypeAttributeAdapter>(adapter);
|
||||
Assert.Equal(expectedRuleName, dataTypeAdapter.RuleName);
|
||||
yield return new object[] { new UrlAttribute(), "url" };
|
||||
yield return new object[] { new CreditCardAttribute(), "creditcard" };
|
||||
yield return new object[] { new EmailAddressAttribute(), "email" };
|
||||
yield return new object[] { new PhoneAttribute(), "phone" };
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("DataTypeAdapters")]
|
||||
public void AdapterFactory_RegistersAdapters_ForDataTypeAttributes(ValidationAttribute attribute,
|
||||
string expectedRuleName)
|
||||
{
|
||||
// Arrange
|
||||
var adapters = new DataAnnotationsModelValidatorProvider().AttributeFactories;
|
||||
var adapterFactory = adapters.Single(kvp => kvp.Key == attribute.GetType()).Value;
|
||||
|
||||
// Act
|
||||
var adapter = adapterFactory(attribute);
|
||||
|
||||
// Assert
|
||||
var dataTypeAdapter = Assert.IsType<DataTypeAttributeAdapter>(adapter);
|
||||
Assert.Equal(expectedRuleName, dataTypeAdapter.RuleName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownValidationAttributeGetsDefaultAdapter()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class RangeAttributeAdapterTest
|
||||
{
|
||||
[Fact]
|
||||
[ReplaceCulture]
|
||||
public void GetClientValidationRules_ReturnsValidationParameters()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(() => null, typeof(string), "Length");
|
||||
var attribute = new RangeAttribute(typeof(decimal), "0", "100");
|
||||
var adapter = new RangeAttributeAdapter(attribute);
|
||||
var context = new ClientModelValidationContext(metadata, provider);
|
||||
|
||||
// Act
|
||||
var rules = adapter.GetClientValidationRules(context);
|
||||
|
||||
// Assert
|
||||
var rule = Assert.Single(rules);
|
||||
Assert.Equal("range", rule.ValidationType);
|
||||
Assert.Equal(2, rule.ValidationParameters.Count);
|
||||
Assert.Equal(0m, rule.ValidationParameters["min"]);
|
||||
Assert.Equal(100m, rule.ValidationParameters["max"]);
|
||||
Assert.Equal(@"The field Length must be between 0 and 100.", rule.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class RequiredAttributeAdapterTest
|
||||
{
|
||||
[Fact]
|
||||
[ReplaceCulture]
|
||||
public void GetClientValidationRules_ReturnsValidationParameters()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(() => null, typeof(string), "Length");
|
||||
var attribute = new RequiredAttribute();
|
||||
var adapter = new RequiredAttributeAdapter(attribute);
|
||||
var context = new ClientModelValidationContext(metadata, provider);
|
||||
|
||||
// Act
|
||||
var rules = adapter.GetClientValidationRules(context);
|
||||
|
||||
// Assert
|
||||
var rule = Assert.Single(rules);
|
||||
Assert.Equal("required", rule.ValidationType);
|
||||
Assert.Empty(rule.ValidationParameters);
|
||||
Assert.Equal("The Length field is required.", rule.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
public class StringLengthAttributeAdapterTest
|
||||
{
|
||||
[Fact]
|
||||
[ReplaceCulture]
|
||||
public void GetClientValidationRules_WithMaxLength_ReturnsValidationParameters()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(() => null, typeof(string), "Length");
|
||||
var attribute = new StringLengthAttribute(8);
|
||||
var adapter = new StringLengthAttributeAdapter(attribute);
|
||||
var context = new ClientModelValidationContext(metadata, provider);
|
||||
|
||||
// Act
|
||||
var rules = adapter.GetClientValidationRules(context);
|
||||
|
||||
// Assert
|
||||
var rule = Assert.Single(rules);
|
||||
Assert.Equal("length", rule.ValidationType);
|
||||
Assert.Equal(1, rule.ValidationParameters.Count);
|
||||
Assert.Equal(8, rule.ValidationParameters["max"]);
|
||||
Assert.Equal("The field Length must be a string with a maximum length of 8.",
|
||||
rule.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[ReplaceCulture]
|
||||
public void GetClientValidationRules_WithMinAndMaxLength_ReturnsValidationParameters()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new DataAnnotationsModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(() => null, typeof(string), "Length");
|
||||
var attribute = new StringLengthAttribute(10) { MinimumLength = 3 };
|
||||
var adapter = new StringLengthAttributeAdapter(attribute);
|
||||
var context = new ClientModelValidationContext(metadata, provider);
|
||||
|
||||
// Act
|
||||
var rules = adapter.GetClientValidationRules(context);
|
||||
|
||||
// Assert
|
||||
var rule = Assert.Single(rules);
|
||||
Assert.Equal("length", rule.ValidationType);
|
||||
Assert.Equal(2, rule.ValidationParameters.Count);
|
||||
Assert.Equal(3, rule.ValidationParameters["min"]);
|
||||
Assert.Equal(10, rule.ValidationParameters["max"]);
|
||||
Assert.Equal("The field Length must be a string with a minimum length of 3 and a maximum length of 10.",
|
||||
rule.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue