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="RequestContext.cs" />
|
||||||
<Compile Include="Validation\AssociatedValidatorProvider.cs" />
|
<Compile Include="Validation\AssociatedValidatorProvider.cs" />
|
||||||
<Compile Include="Validation\ClientModelValidationContext.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\CompareAttributeAdapter.cs" />
|
||||||
<Compile Include="Validation\CompositeModelValidator.cs" />
|
<Compile Include="Validation\CompositeModelValidator.cs" />
|
||||||
<Compile Include="Validation\DataAnnotationsModelValidator.cs" />
|
<Compile Include="Validation\DataAnnotationsModelValidator.cs" />
|
||||||
|
|
@ -89,8 +92,11 @@
|
||||||
<Compile Include="Validation\ModelClientValidationEqualToRule.cs" />
|
<Compile Include="Validation\ModelClientValidationEqualToRule.cs" />
|
||||||
<Compile Include="Validation\ModelClientValidationMaxLengthRule.cs" />
|
<Compile Include="Validation\ModelClientValidationMaxLengthRule.cs" />
|
||||||
<Compile Include="Validation\ModelClientValidationMinLengthRule.cs" />
|
<Compile Include="Validation\ModelClientValidationMinLengthRule.cs" />
|
||||||
|
<Compile Include="Validation\ModelClientValidationRangeRule.cs" />
|
||||||
<Compile Include="Validation\ModelClientValidationRegexRule.cs" />
|
<Compile Include="Validation\ModelClientValidationRegexRule.cs" />
|
||||||
|
<Compile Include="Validation\ModelClientValidationRequiredRule.cs" />
|
||||||
<Compile Include="Validation\ModelClientValidationRule.cs" />
|
<Compile Include="Validation\ModelClientValidationRule.cs" />
|
||||||
|
<Compile Include="Validation\ModelClientValidationStringLengthRule.cs" />
|
||||||
<Compile Include="Validation\ModelValidatedEventArgs.cs" />
|
<Compile Include="Validation\ModelValidatedEventArgs.cs" />
|
||||||
<Compile Include="Validation\ModelValidatingEventArgs.cs" />
|
<Compile Include="Validation\ModelValidatingEventArgs.cs" />
|
||||||
<Compile Include="Validation\ModelValidationContext.cs" />
|
<Compile Include="Validation\ModelValidationContext.cs" />
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
AddValidationAttributeAdapter(dict, typeof(CompareAttribute),
|
AddValidationAttributeAdapter(dict, typeof(CompareAttribute),
|
||||||
(attribute) => new CompareAttributeAdapter((CompareAttribute)attribute));
|
(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");
|
AddDataTypeAttributeAdapter(dict, typeof(UrlAttribute), "url");
|
||||||
|
|
||||||
return dict;
|
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="ModelBindingContextTest.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs" />
|
<Compile Include="Properties\Resources.Designer.cs" />
|
||||||
<Compile Include="Utils\SimpleHttpValueProvider.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\AssociatedValidatorProviderTest.cs" />
|
||||||
<Compile Include="Validation\CompareAttributeTest.cs" />
|
<Compile Include="Validation\CompareAttributeTest.cs" />
|
||||||
<Compile Include="Validation\DataAnnotationsModelValidatorProviderTest.cs" />
|
<Compile Include="Validation\DataAnnotationsModelValidatorProviderTest.cs" />
|
||||||
|
|
|
||||||
|
|
@ -13,51 +13,74 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
private readonly DataAnnotationsModelMetadataProvider _metadataProvider = new DataAnnotationsModelMetadataProvider();
|
private readonly DataAnnotationsModelMetadataProvider _metadataProvider = new DataAnnotationsModelMetadataProvider();
|
||||||
|
|
||||||
public static IEnumerable<object[]> KnownAdapterTypeData
|
public static IEnumerable<object[]> DataAnnotationAdapters
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new object[] { typeof(RegularExpressionAttribute),
|
yield return new object[] { new RegularExpressionAttribute("abc"),
|
||||||
new RegularExpressionAttribute("abc"),
|
typeof(RegularExpressionAttributeAdapter) };
|
||||||
typeof(RegularExpressionAttributeAdapter), null };
|
|
||||||
|
|
||||||
yield return new object[] { typeof(MaxLengthAttribute),
|
yield return new object[] { new MaxLengthAttribute(),
|
||||||
new MaxLengthAttribute(),
|
typeof(MaxLengthAttributeAdapter) };
|
||||||
typeof(MaxLengthAttributeAdapter), null };
|
|
||||||
|
|
||||||
yield return new object[] { typeof(MinLengthAttribute),
|
yield return new object[] { new MinLengthAttribute(1),
|
||||||
new MinLengthAttribute(1),
|
typeof(MinLengthAttributeAdapter) };
|
||||||
typeof(MinLengthAttributeAdapter), null };
|
|
||||||
|
|
||||||
yield return new object[] { typeof(UrlAttribute),
|
yield return new object[] { new RangeAttribute(1, 100),
|
||||||
new UrlAttribute(),
|
typeof(RangeAttributeAdapter) };
|
||||||
typeof(DataTypeAttributeAdapter), "url" };
|
|
||||||
|
yield return new object[] { new StringLengthAttribute(6),
|
||||||
|
typeof(StringLengthAttributeAdapter) };
|
||||||
|
|
||||||
|
yield return new object[] { new RequiredAttribute(),
|
||||||
|
typeof(RequiredAttributeAdapter) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData("KnownAdapterTypeData")]
|
[MemberData("DataAnnotationAdapters")]
|
||||||
public void AdapterForKnownTypeRegistered(Type attributeType,
|
public void AdapterFactory_RegistersAdapters_ForDataAnnotationAttributes(ValidationAttribute attribute,
|
||||||
ValidationAttribute validationAttr,
|
Type expectedAdapterType)
|
||||||
Type expectedAdapterType,
|
|
||||||
string expectedRuleName)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var adapters = new DataAnnotationsModelValidatorProvider().AttributeFactories;
|
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
|
// Act
|
||||||
var adapter = adapterFactory(validationAttr);
|
var adapter = adapterFactory(attribute);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType(expectedAdapterType, adapter);
|
Assert.IsType(expectedAdapterType, adapter);
|
||||||
if (expectedRuleName != null)
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> DataTypeAdapters
|
||||||
|
{
|
||||||
|
get
|
||||||
{
|
{
|
||||||
var dataTypeAdapter = Assert.IsType<DataTypeAttributeAdapter>(adapter);
|
yield return new object[] { new UrlAttribute(), "url" };
|
||||||
Assert.Equal(expectedRuleName, dataTypeAdapter.RuleName);
|
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]
|
[Fact]
|
||||||
public void UnknownValidationAttributeGetsDefaultAdapter()
|
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