linux-packaging-mono/external/aspnetwebstack/test/System.Web.Mvc.Test/Test/DataAnnotationsModelValidatorProviderTest.cs
Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

728 lines
30 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class DataAnnotationsModelValidatorProviderTest
{
// Validation attribute adapter registration
private class MyValidationAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
throw new NotImplementedException();
}
}
private class MyValidationAttributeAdapter : DataAnnotationsModelValidator<MyValidationAttribute>
{
public MyValidationAttributeAdapter(ModelMetadata metadata, ControllerContext context, MyValidationAttribute attribute)
: base(metadata, context, attribute)
{
}
}
private class MyValidationAttributeAdapterBadCtor : ModelValidator
{
public MyValidationAttributeAdapterBadCtor(ModelMetadata metadata, ControllerContext context)
: base(metadata, context)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
throw new NotImplementedException();
}
}
private class MyDefaultValidationAttributeAdapter : DataAnnotationsModelValidator
{
public MyDefaultValidationAttributeAdapter(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
: base(metadata, context, attribute)
{
}
}
[MyValidation]
private class MyValidatedClass
{
}
[Fact]
public void RegisterAdapter()
{
var oldFactories = DataAnnotationsModelValidatorProvider.AttributeFactories;
try
{
// Arrange
DataAnnotationsModelValidatorProvider.AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>();
// Act
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyValidationAttribute), typeof(MyValidationAttributeAdapter));
// Assert
var type = DataAnnotationsModelValidatorProvider.AttributeFactories.Keys.Single();
Assert.Equal(typeof(MyValidationAttribute), type);
var factory = DataAnnotationsModelValidatorProvider.AttributeFactories.Values.Single();
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var attribute = new MyValidationAttribute();
var validator = factory(metadata, context, attribute);
Assert.IsType<MyValidationAttributeAdapter>(validator);
}
finally
{
DataAnnotationsModelValidatorProvider.AttributeFactories = oldFactories;
}
}
[Fact]
public void RegisterAdapterGuardClauses()
{
// Attribute type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterAdapter(null, typeof(MyValidationAttributeAdapter)),
"attributeType");
// Adapter type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyValidationAttribute), null),
"adapterType");
// Validation attribute must derive from ValidationAttribute
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(object), typeof(MyValidationAttributeAdapter)),
"The type System.Object must derive from System.ComponentModel.DataAnnotations.ValidationAttribute\r\nParameter name: attributeType");
// Adapter must derive from ModelValidator
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyValidationAttribute), typeof(object)),
"The type System.Object must derive from System.Web.Mvc.ModelValidator\r\nParameter name: adapterType");
// Adapter must have the expected constructor
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyValidationAttribute), typeof(MyValidationAttributeAdapterBadCtor)),
"The type System.Web.Mvc.Test.DataAnnotationsModelValidatorProviderTest+MyValidationAttributeAdapterBadCtor must have a public constructor which accepts three parameters of types System.Web.Mvc.ModelMetadata, System.Web.Mvc.ControllerContext, and System.Web.Mvc.Test.DataAnnotationsModelValidatorProviderTest+MyValidationAttribute\r\nParameter name: adapterType");
}
[Fact]
public void RegisterAdapterFactory()
{
var oldFactories = DataAnnotationsModelValidatorProvider.AttributeFactories;
try
{
// Arrange
DataAnnotationsModelValidatorProvider.AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>();
DataAnnotationsModelValidationFactory factory = delegate { return null; };
// Act
DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(typeof(MyValidationAttribute), factory);
// Assert
var type = DataAnnotationsModelValidatorProvider.AttributeFactories.Keys.Single();
Assert.Equal(typeof(MyValidationAttribute), type);
Assert.Same(factory, DataAnnotationsModelValidatorProvider.AttributeFactories.Values.Single());
}
finally
{
DataAnnotationsModelValidatorProvider.AttributeFactories = oldFactories;
}
}
[Fact]
public void RegisterAdapterFactoryGuardClauses()
{
DataAnnotationsModelValidationFactory factory = (metadata, context, attribute) => null;
// Attribute type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(null, factory),
"attributeType");
// Factory cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(typeof(MyValidationAttribute), null),
"factory");
// Validation attribute must derive from ValidationAttribute
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(typeof(object), factory),
"The type System.Object must derive from System.ComponentModel.DataAnnotations.ValidationAttribute\r\nParameter name: attributeType");
}
[Fact]
public void RegisterDefaultAdapter()
{
var oldFactory = DataAnnotationsModelValidatorProvider.DefaultAttributeFactory;
try
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(MyValidatedClass));
var context = new ControllerContext();
DataAnnotationsModelValidatorProvider.RegisterDefaultAdapter(typeof(MyDefaultValidationAttributeAdapter));
// Act
var result = new DataAnnotationsModelValidatorProvider().GetValidators(metadata, context).Single();
// Assert
Assert.IsType<MyDefaultValidationAttributeAdapter>(result);
}
finally
{
DataAnnotationsModelValidatorProvider.DefaultAttributeFactory = oldFactory;
}
}
[Fact]
public void RegisterDefaultAdapterGuardClauses()
{
// Adapter type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultAdapter(null),
"adapterType");
// Adapter must derive from ModelValidator
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultAdapter(typeof(object)),
"The type System.Object must derive from System.Web.Mvc.ModelValidator\r\nParameter name: adapterType");
// Adapter must have the expected constructor
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultAdapter(typeof(MyValidationAttributeAdapterBadCtor)),
"The type System.Web.Mvc.Test.DataAnnotationsModelValidatorProviderTest+MyValidationAttributeAdapterBadCtor must have a public constructor which accepts three parameters of types System.Web.Mvc.ModelMetadata, System.Web.Mvc.ControllerContext, and System.ComponentModel.DataAnnotations.ValidationAttribute\r\nParameter name: adapterType");
}
[Fact]
public void RegisterDefaultAdapterFactory()
{
var oldFactory = DataAnnotationsModelValidatorProvider.DefaultAttributeFactory;
try
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(MyValidatedClass));
var context = new ControllerContext();
ModelValidator validator = new Mock<ModelValidator>(metadata, context).Object;
DataAnnotationsModelValidationFactory factory = delegate { return validator; };
DataAnnotationsModelValidatorProvider.RegisterDefaultAdapterFactory(factory);
// Act
var result = new DataAnnotationsModelValidatorProvider().GetValidators(metadata, context).Single();
// Assert
Assert.Same(validator, result);
}
finally
{
DataAnnotationsModelValidatorProvider.DefaultAttributeFactory = oldFactory;
}
}
[Fact]
public void RegisterDefaultAdapterFactoryGuardClauses()
{
// Factory cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultAdapterFactory(null),
"factory");
}
// IValidatableObject adapter registration
private class MyValidatableAdapter : ModelValidator
{
public MyValidatableAdapter(ModelMetadata metadata, ControllerContext context)
: base(metadata, context)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
throw new NotImplementedException();
}
}
private class MyValidatableAdapterBadCtor : ModelValidator
{
public MyValidatableAdapterBadCtor(ModelMetadata metadata, ControllerContext context, int unused)
: base(metadata, context)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
throw new NotImplementedException();
}
}
private class MyValidatableClass : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
throw new NotImplementedException();
}
}
[Fact]
public void RegisterValidatableObjectAdapter()
{
var oldFactories = DataAnnotationsModelValidatorProvider.ValidatableFactories;
try
{
// Arrange
DataAnnotationsModelValidatorProvider.ValidatableFactories = new Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory>();
IValidatableObject validatable = new Mock<IValidatableObject>().Object;
// Act
DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(validatable.GetType(), typeof(MyValidatableAdapter));
// Assert
var type = DataAnnotationsModelValidatorProvider.ValidatableFactories.Keys.Single();
Assert.Equal(validatable.GetType(), type);
var factory = DataAnnotationsModelValidatorProvider.ValidatableFactories.Values.Single();
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var validator = factory(metadata, context);
Assert.IsType<MyValidatableAdapter>(validator);
}
finally
{
DataAnnotationsModelValidatorProvider.ValidatableFactories = oldFactories;
}
}
[Fact]
public void RegisterValidatableObjectAdapterGuardClauses()
{
// Attribute type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(null, typeof(MyValidatableAdapter)),
"modelType");
// Adapter type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(typeof(MyValidatableClass), null),
"adapterType");
// Validation attribute must derive from ValidationAttribute
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(typeof(object), typeof(MyValidatableAdapter)),
"The type System.Object must derive from System.ComponentModel.DataAnnotations.IValidatableObject\r\nParameter name: modelType");
// Adapter must derive from ModelValidator
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(typeof(MyValidatableClass), typeof(object)),
"The type System.Object must derive from System.Web.Mvc.ModelValidator\r\nParameter name: adapterType");
// Adapter must have the expected constructor
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapter(typeof(MyValidatableClass), typeof(MyValidatableAdapterBadCtor)),
"The type System.Web.Mvc.Test.DataAnnotationsModelValidatorProviderTest+MyValidatableAdapterBadCtor must have a public constructor which accepts two parameters of types System.Web.Mvc.ModelMetadata and System.Web.Mvc.ControllerContext.\r\nParameter name: adapterType");
}
[Fact]
public void RegisterValidatableObjectAdapterFactory()
{
var oldFactories = DataAnnotationsModelValidatorProvider.ValidatableFactories;
try
{
// Arrange
DataAnnotationsModelValidatorProvider.ValidatableFactories = new Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory>();
DataAnnotationsValidatableObjectAdapterFactory factory = delegate { return null; };
// Act
DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapterFactory(typeof(MyValidatableClass), factory);
// Assert
var type = DataAnnotationsModelValidatorProvider.ValidatableFactories.Keys.Single();
Assert.Equal(typeof(MyValidatableClass), type);
Assert.Same(factory, DataAnnotationsModelValidatorProvider.ValidatableFactories.Values.Single());
}
finally
{
DataAnnotationsModelValidatorProvider.ValidatableFactories = oldFactories;
}
}
[Fact]
public void RegisterValidatableObjectAdapterFactoryGuardClauses()
{
DataAnnotationsValidatableObjectAdapterFactory factory = (metadata, context) => null;
// Attribute type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapterFactory(null, factory),
"modelType");
// Factory cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapterFactory(typeof(MyValidatableClass), null),
"factory");
// Validation attribute must derive from ValidationAttribute
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterValidatableObjectAdapterFactory(typeof(object), factory),
"The type System.Object must derive from System.ComponentModel.DataAnnotations.IValidatableObject\r\nParameter name: modelType");
}
[Fact]
public void RegisterDefaultValidatableObjectAdapter()
{
var oldFactory = DataAnnotationsModelValidatorProvider.DefaultValidatableFactory;
try
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(MyValidatableClass));
var context = new ControllerContext();
DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapter(typeof(MyValidatableAdapter));
// Act
var result = new DataAnnotationsModelValidatorProvider().GetValidators(metadata, context).Single();
// Assert
Assert.IsType<MyValidatableAdapter>(result);
}
finally
{
DataAnnotationsModelValidatorProvider.DefaultValidatableFactory = oldFactory;
}
}
[Fact]
public void RegisterDefaultValidatableObjectAdapterGuardClauses()
{
// Adapter type cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapter(null),
"adapterType");
// Adapter must derive from ModelValidator
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapter(typeof(object)),
"The type System.Object must derive from System.Web.Mvc.ModelValidator\r\nParameter name: adapterType");
// Adapter must have the expected constructor
Assert.Throws<ArgumentException>(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapter(typeof(MyValidatableAdapterBadCtor)),
"The type System.Web.Mvc.Test.DataAnnotationsModelValidatorProviderTest+MyValidatableAdapterBadCtor must have a public constructor which accepts two parameters of types System.Web.Mvc.ModelMetadata and System.Web.Mvc.ControllerContext.\r\nParameter name: adapterType");
}
[Fact]
public void RegisterDefaultValidatableObjectAdapterFactory()
{
var oldFactory = DataAnnotationsModelValidatorProvider.DefaultValidatableFactory;
try
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(MyValidatableClass));
var context = new ControllerContext();
ModelValidator validator = new Mock<ModelValidator>(metadata, context).Object;
DataAnnotationsValidatableObjectAdapterFactory factory = delegate { return validator; };
DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory(factory);
// Act
var result = new DataAnnotationsModelValidatorProvider().GetValidators(metadata, context).Single();
// Assert
Assert.Same(validator, result);
}
finally
{
DataAnnotationsModelValidatorProvider.DefaultValidatableFactory = oldFactory;
}
}
[Fact]
public void RegisterDefaultValidatableObjectAdapterFactoryGuardClauses()
{
// Factory cannot be null
Assert.ThrowsArgumentNull(
() => DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory(null),
"factory");
}
// Pre-configured adapters
[Fact]
public void AdapterForRangeAttributeRegistered()
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var adapters = DataAnnotationsModelValidatorProvider.AttributeFactories;
var adapterFactory = adapters.Single(kvp => kvp.Key == typeof(RangeAttribute)).Value;
// Act
var adapter = adapterFactory(metadata, context, new RangeAttribute(1, 100));
// Assert
Assert.IsType<RangeAttributeAdapter>(adapter);
}
[Fact]
public void AdapterForRegularExpressionAttributeRegistered()
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var adapters = DataAnnotationsModelValidatorProvider.AttributeFactories;
var adapterFactory = adapters.Single(kvp => kvp.Key == typeof(RegularExpressionAttribute)).Value;
// Act
var adapter = adapterFactory(metadata, context, new RegularExpressionAttribute("abc"));
// Assert
Assert.IsType<RegularExpressionAttributeAdapter>(adapter);
}
[Fact]
public void AdapterForRequiredAttributeRegistered()
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var adapters = DataAnnotationsModelValidatorProvider.AttributeFactories;
var adapterFactory = adapters.Single(kvp => kvp.Key == typeof(RequiredAttribute)).Value;
// Act
var adapter = adapterFactory(metadata, context, new RequiredAttribute());
// Assert
Assert.IsType<RequiredAttributeAdapter>(adapter);
}
[Fact]
public void AdapterForStringLengthAttributeRegistered()
{
// Arrange
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(object));
var context = new ControllerContext();
var adapters = DataAnnotationsModelValidatorProvider.AttributeFactories;
var adapterFactory = adapters.Single(kvp => kvp.Key == typeof(StringLengthAttribute)).Value;
// Act
var adapter = adapterFactory(metadata, context, new StringLengthAttribute(6));
// Assert
Assert.IsType<StringLengthAttributeAdapter>(adapter);
}
// Default adapter factory for unknown attribute type
[Fact]
public void UnknownValidationAttributeGetsDefaultAdapter()
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(DummyClassWithDummyValidationAttribute));
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
var validator = validators.Single();
Assert.IsType<DataAnnotationsModelValidator>(validator);
}
private class DummyValidationAttribute : ValidationAttribute
{
}
[DummyValidation]
private class DummyClassWithDummyValidationAttribute
{
}
// Default IValidatableObject adapter factory
[Fact]
public void IValidatableObjectGetsAValidator()
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var mockValidatable = new Mock<IValidatableObject>();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, mockValidatable.Object.GetType());
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
Assert.Single(validators);
}
// Implicit [Required] attribute
[Fact]
public void ReferenceTypesDontGetImplicitRequiredAttribute()
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(string));
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
Assert.Empty(validators);
}
[Fact]
public void NonNullableValueTypesGetImplicitRequiredAttribute()
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(() => null, typeof(DummyRequiredAttributeHelperClass), "WithoutAttribute");
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
ModelValidator validator = validators.Single();
ModelClientValidationRule rule = validator.GetClientValidationRules().Single();
Assert.IsType<ModelClientValidationRequiredRule>(rule);
}
[Fact]
public void NonNullableValueTypesWithExplicitRequiredAttributeDoesntGetImplictRequiredAttribute()
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(() => null, typeof(DummyRequiredAttributeHelperClass), "WithAttribute");
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
ModelValidator validator = validators.Single();
ModelClientValidationRule rule = validator.GetClientValidationRules().Single();
Assert.IsType<ModelClientValidationRequiredRule>(rule);
Assert.Equal("Custom Required Message", rule.ErrorMessage);
}
[Fact]
public void NonNullableValueTypeDoesntGetImplicitRequiredAttributeWhenFlagIsOff()
{
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
try
{
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(() => null, typeof(DummyRequiredAttributeHelperClass), "WithoutAttribute");
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
Assert.Empty(validators);
}
finally
{
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = true;
}
}
private class DummyRequiredAttributeHelperClass
{
[Required(ErrorMessage = "Custom Required Message")]
public int WithAttribute { get; set; }
public int WithoutAttribute { get; set; }
}
// Integration with metadata system
[Fact]
public void DoesNotReadPropertyValue()
{
// Arrange
ObservableModel model = new ObservableModel();
ModelMetadata metadata = new DataAnnotationsModelMetadataProvider().GetMetadataForProperty(() => model.TheProperty, typeof(ObservableModel), "TheProperty");
ControllerContext controllerContext = new ControllerContext();
// Act
ModelValidator[] validators = new DataAnnotationsModelValidatorProvider().GetValidators(metadata, controllerContext).ToArray();
ModelValidationResult[] results = validators.SelectMany(o => o.Validate(model)).ToArray();
// Assert
Assert.Empty(validators);
Assert.False(model.PropertyWasRead());
}
private class ObservableModel
{
private bool _propertyWasRead;
public string TheProperty
{
get
{
_propertyWasRead = true;
return "Hello";
}
}
public bool PropertyWasRead()
{
return _propertyWasRead;
}
}
private class BaseModel
{
public virtual string MyProperty { get; set; }
}
private class DerivedModel : BaseModel
{
[StringLength(10)]
public override string MyProperty
{
get { return base.MyProperty; }
set { base.MyProperty = value; }
}
}
[Fact]
public void GetValidatorsReturnsClientValidatorForDerivedTypeAppliedAgainstBaseTypeViaFromLambdaExpression()
{ // Dev10 Bug #868619
// Arrange
var provider = new DataAnnotationsModelValidatorProvider();
var context = new ControllerContext();
var viewdata = new ViewDataDictionary<DerivedModel>();
var metadata = ModelMetadata.FromLambdaExpression(m => m.MyProperty, viewdata); // Bug is in FromLambdaExpression
// Act
IEnumerable<ModelValidator> validators = provider.GetValidators(metadata, context);
// Assert
ModelValidator validator = validators.Single();
ModelClientValidationRule clientRule = validator.GetClientValidationRules().Single();
Assert.IsType<ModelClientValidationStringLengthRule>(clientRule);
Assert.Equal(10, clientRule.ValidationParameters["max"]);
}
}
}