Excellent - thank you
New Post: Validate RuleSet and property array
Created Issue: 3.4.6 Destabilize the runtime VerificationException [7114]
I believe this version of FluentValidation has a work-around for a reflection bug introduced in .NET 4.5, however I'm still getting a VerificationException, as described here http://elegantcode.com/2012/08/23/net-4-5-operation-could-destabilize-the-runtime-yikes/
VerificationException is thrown at this point:
MyValidator : AbstractValidator<MyObj>
ctor {
RuleFor(x => x.SomeProperty).Equal(true);
}
at FluentValidation.Resources.LocalizedStringSource.CreateFromExpression(Expression`1 expression, IResourceAccessorBuilder resourceProviderSelectionStrategy) in c:\projects\FluentValidation\src\FluentValidation\Resources\LocalizedStringSource.cs:line 66
at FluentValidation.Validators.PropertyValidator..ctor(Expression`1 errorMessageResourceSelector) in c:\projects\FluentValidation\src\FluentValidation\Validators\PropertyValidator.cs:line 46
at FluentValidation.Validators.EqualValidator..ctor(Object valueToCompare, IEqualityComparer comparer) in c:\projects\FluentValidation\src\FluentValidation\Validators\EqualValidator.cs:line 37
at FluentValidation.DefaultValidatorExtensions.Equal[T,TProperty](IRuleBuilder`2 ruleBuilder, TProperty toCompare, IEqualityComparer comparer) in c:\projects\FluentValidation\src\FluentValidation\DefaultValidatorExtensions.cs:line 143
at MyValidator..ctor() in MyValidator.cs:line 22
Edited Issue: 3.4.6 Destabilize the runtime VerificationException [7114]
Update:
I was able to run outside the debugger and eventually narrowed it down to intell-trace. Disable intelli-trace if you hit this issue in 3.4.6.
--
I'm using FluentValidation 3.4.6, and the target framework of my project is .net 4. I've checked my solution thoroughly to ensure there are no references to older versions of FluentValidation.
I believe this version of FluentValidation has a work-around for a reflection bug introduced in .NET 4.5, however I'm still getting a VerificationException, as described here http://elegantcode.com/2012/08/23/net-4-5-operation-could-destabilize-the-runtime-yikes/
VerificationException is thrown at this point:
MyValidator : AbstractValidator<MyObj>
ctor {
RuleFor(x => x.SomeProperty).Equal(true);
}
at FluentValidation.Resources.LocalizedStringSource.CreateFromExpression(Expression`1 expression, IResourceAccessorBuilder resourceProviderSelectionStrategy) in c:\projects\FluentValidation\src\FluentValidation\Resources\LocalizedStringSource.cs:line 66
at FluentValidation.Validators.PropertyValidator..ctor(Expression`1 errorMessageResourceSelector) in c:\projects\FluentValidation\src\FluentValidation\Validators\PropertyValidator.cs:line 46
at FluentValidation.Validators.EqualValidator..ctor(Object valueToCompare, IEqualityComparer comparer) in c:\projects\FluentValidation\src\FluentValidation\Validators\EqualValidator.cs:line 37
at FluentValidation.DefaultValidatorExtensions.Equal[T,TProperty](IRuleBuilder`2 ruleBuilder, TProperty toCompare, IEqualityComparer comparer) in c:\projects\FluentValidation\src\FluentValidation\DefaultValidatorExtensions.cs:line 143
at MyValidator..ctor() in MyValidator.cs:line 22
Created Issue: PEVerification on type-safety fails [7115]
PEVerify execution results:
c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>peverify FluentValidation.dll
Microsoft (R) .NET Framework PE Verifier. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000037). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000038). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000039). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000037). [token:0x0900002C]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000038). [token:0x0900002C]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000039). [token:0x0900002C]
6 Error(s) Verifying FluentValidation.dll
P.S.: We use FluentValidation in developing applications for app portal with strict security policy, and it doesn't accept the ones that don't meet type safety requirements.
Closed Issue: PEVerification on type-safety fails [7115]
PEVerify execution results:
c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>peverify FluentValidation.dll
Microsoft (R) .NET Framework PE Verifier. Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000037). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000038). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x02000010; interface:0x0200000b; method:0x06000039). [token:0x09000018]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000037). [token:0x0900002C]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000038). [token:0x0900002C]
[MD]: Error: Class implements interface but not method (class:0x0200002c; interface:0x0200000b; method:0x06000039). [token:0x0900002C]
6 Error(s) Verifying FluentValidation.dll
P.S.: We use FluentValidation in developing applications for app portal with strict security policy, and it doesn't accept the ones that don't meet type safety requirements.
Comments: You'll need to compile your own version - I'm not currently intending to remove IFluentInterface.
New Post: Apply validator to one item in array
Hello and sorry for bringing up an old topic but I have a issue with single array element validation. I'm trying to use exact rule as Jeremy suggested:
RuleFor(x => x.SomeArrayProperty[0]).SetValidator(new WhateverValidator()).When(x => x.SomeArrayProperty.Length > 0).OverridePropertyName("whatever");
But for some unknown reason I keep getting null reference exception:
[NullReferenceException: Object reference not set to an instance of an object.] FluentValidation.<>c__DisplayClass13.<GetRulesForMember>b__10(PropertyRule rule) in c:\projects\FluentValidation\src\FluentValidation\ValidatorDescriptor.cs:61 System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +6379289 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +471 System.Linq.Enumerable.ToList(IEnumerable`1 source) +79 FluentValidation.ValidatorDescriptor`1.GetRulesForMember(String name) in c:\projects\FluentValidation\src\FluentValidation\ValidatorDescriptor.cs:64 FluentValidation.Mvc.FluentValidationModelValidatorProvider.GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context, IValidator validator) in c:\projects\FluentValidation\src\FluentValidation.Mvc3\FluentValidationModelValidatorProvider.cs:88 System.Linq.<SelectManyIterator>d__14`2.MoveNext() +266 System.Linq.WhereEnumerableIterator`1.MoveNext() +195 System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +247 System.Web.Mvc.DefaultModelBinder.SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, Object value) +488 System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +678
It seems that the only way when it does not throw an exception is when I specify rule for entire collection like RuleFor(x => x.Items) instead of RuleFor(x => x.Items[0]). But that is not what I need. Any ideas why it might not work?
New Post: Apply validator to one item in array
With some tweaks I made it work. It seems that simply specifying RuleFor(x => x.Array[0]) is not enough or I might be missing something. For me this solution was good enough:
RuleFor(x => x.Array[0].Property).NotEmpty().OverridePropertyName("Array[0].Property")
What I found to be quite odd for OverridePropertyName behavior is that it doesn't completly override the property name when you have a validator for element array instead of specific element (AbstractValidator<Element[]>) and a rule like this:
RoleFor(x => x[0].Property).NotEmpty().OverridePropertyName("Array[0].Property")
In this case the property name is equal to "Array.Array[0].Property" instead of the specified value. My guess it's intentional but I still would like to have a way to completly override property names for specific scenarios.
Created Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Commented Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Comments: Hi FluentValidation only supports integration with ASP.NET MVC's validation infrastructure. Because of the strange way that MVC and WebAPI were bolted together, their validation process go through completely separate pipelines so the existing validation integration doesn't just work with WebAPI. This isn't something that I personally intend to add at the moment, but there is an outstanding pull request that adds support for WebAPI. It's not currently at a point where I could merge it in, but it might be a useful starting point for you.
Commented Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Comments: Ok, that sounds good. Could You drop me a link to where I could find that implementation ? Thanx, Marty
Commented Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Comments: Oh, Found it. Thanx
Commented Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Comments: http://fluentvalidation.codeplex.com/SourceControl/network/forks/havard/webapisupport/contribution/2253
Commented Issue: Doesn't hook up to MVC ApiControllers [7116]
I'm trying to use fluent validation for my MVC 4 WebApi project.
But it only seems to work on controllers that are inherited from the Controller type.
When I use MyController : Controller -> works fine (ModelState.IsValid returns False)
but when I use MyController :ApiController ... nothing.
How can I make this work on the WebApi ?
Comments: Too bad that it only build's on .Net 4.5 :( Doesn't work on .Net 4.0..
New Post: NullReferenceException using FluentValidation in MVC3
I have set up a test sample using fluent validation in a standard ASP.NET MVC3 template application in Visual Studio 2010.
This is my model code:
[Validator(typeof(TestValidator))] public class TestModel { public bool IsCreate { get; set; } public int? TestID { get; set; } public string TestName { get; set; } public string TestDescription { get; set; } public string TestHidden { get; set; } } public class TestValidator : AbstractValidator<TestModel> { public TestValidator() { RuleFor(t => t).Must(TestIsDefined).WithMessage("User must select existing customer or provide at least a new customer name"); RuleFor(t => t.TestName).Length(0, 50); RuleFor(t => t.TestDescription).Length(0, 100); } private bool TestIsDefined(TestModel model) { return (model.TestID.HasValue || (string.IsNullOrWhiteSpace(model.TestName) && string.IsNullOrWhiteSpace(model.TestDescription))); } }
I am using the Must() method to create a custom validation based on the current state of the model. This is fully wired up to MVC3 via the fluentvalidation.mvc3 package.
In the view, as soon as I reference the model using Razor (e.g. @Html.EditorFor()), I receive a NullReferenceException at FluentValidation.ValidatorDescriptor`1.<>c__DisplayClass13.<GetRulesForMember>b__10(PropertyRule rule) in c:\projects\FluentValidation\src\FluentValidation\ValidatorDescriptor.cs:line 61
I am fairly new to FluentValidation. Is there anything that I am missing or have done incorrectly that would cause this issue?
New Post: NullReferenceException using FluentValidation in MVC3
Hi
Which version of FluentValidation are you running?
There was an issue with old builds of FluentValidation where rules defined without a property (such as RuleFor(t => t)) would throw an exception, but this was fixed over a year ago. Note that it still isn't recommended to use rules like RuleFor(t => t) - with FluentValidation it's really best to define rules against a property.
If you're running the latest version (3.4.x) then please put together a unit test that reproduces the issue. Thanks.
Jeremy
New Post: MVC - set validator type of Validator attribute at runtime
We've got a model and view where the validation changes based on the current status of the data in the model. On the server side, we've hooked up a composite validator that takes the current status and registers different base validators based on the status. This works with no problem.
But we want to wire up the validation the client-side. Right now, we can decorate our model with a specific validator type that is static and applicable for only a given status, but we'd like to change the validator type on the fly based on the current status of the model.
We'd like to do something like this:
[Validator(typeof(RequestValidatorInitial))]� � public class RequestViewModel : IAuditLetterRequest, IAuditLetterSystemData� � { ... }
But change RequestValidatorInitial to some other type at runtime. Right now, I'm trying to accomplish this by creating a custom validator attribute that allows me to change the validator type then changing the type in the controller:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] public class CustomValidatorAttribute : ValidatorAttribute { /// <summary> /// The type of the validator used to validate the current type. /// </summary> new public Type ValidatorType { get; set; } /// <summary> /// Creates an instance of the ValidatorAttribute allowing a validator type to be specified. /// </summary> public CustomValidatorAttribute(Type validatorType) : base (validatorType) { } }
and then
var attributes = TypeDescriptor.GetAttributes(viewModel); ((CustomValidatorAttribute)attributes[typeof(CustomValidatorAttribute)]).ValidatorType = typeof(SecondaryValidator);
When I examine the attributes of the model after this code, the attribute shows a type of SecondaryValidator, but the view doesn't reflect the change in validation (a new rule is added to the secondary validator that isn't in the first, and that rule doesn't appear on the client-side).
Any ideas how to change the validator type dynamically at runtime such that it will be reflected in the view?
New Post: MVC - set validator type of Validator attribute at runtime
Your best bet is to write a custom ValidatorFactory implementation, rather than using the AttributedValidatorFactory. This way you can use your own logic to determine how the validator instance gets instantiated. Examples:
http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=ValidatorFactory
http://fluentvalidation.codeplex.com/wikipage?title=ValidatorFactory
However, you don't get access to the viewmodel instance in the factory - only the type. If you need access to the instance then you may want to look at a custom ModelValidatorProvider. Here's FluentValidation's implementation (specifically, overriding the GetValidators method): https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation.Mvc3/FluentValidationModelValidatorProvider.cs
Jeremy
Source code checked in, #46a5d5bfaa70
New Post: NullReferenceException using FluentValidation in MVC3
I am using FluentValidation and FluentValidation.MVC3 version 3.4.6. I also observed the same exception when using the following in my validator constructor:
Custom(t => { return !t.TestID.HasValue && (string.IsNullOrWhiteSpace(t.TestName) && (string.IsNullOrWhiteSpace(t.TestDescription))) ? new ValidationFailure(string.Empty, "User must select existing test or provide new test name and description") : null; });
I don't have a unit test to reproduce the issue, but I created a test MVC3 website using the MS template that is very straightforward. If you would like, I could zip it up. Would you like me to email it to you directly?
New Post: NullReferenceException using FluentValidation in MVC3
Sorry, the Custom() snippet above does work. There is another scenario that produces the same exception
public class TestValidator : AbstractValidator<TestModel> { public TestValidator() { //RuleFor(t => t).Must(TestIsDefined).WithMessage("User must select existing customer or provide at least a new customer name"); //Custom(t => { return !t.TestID.HasValue && (string.IsNullOrWhiteSpace(t.TestName) && (string.IsNullOrWhiteSpace(t.TestDescription))) ? new ValidationFailure(string.Empty, "User must select existing test or provide new test name and description") : null; }); RuleFor(r => r.TestID).NotEmpty().When(r => !r.IsCreate); RuleFor(r => r).SetValidator(new CustomValidator()).When(r => r.IsCreate); RuleFor(t => t.TestName).Length(0, 50); RuleFor(t => t.TestDescription).Length(0, 100); } private bool TestIsDefined(TestModel model) { return (model.TestID.HasValue || (string.IsNullOrWhiteSpace(model.TestName) && string.IsNullOrWhiteSpace(model.TestDescription))); } } public class CustomValidator : AbstractValidator<TestModel> { public CustomValidator() { RuleFor(r => r.TestName).NotEmpty().Length(0, 50); RuleFor(r => r.TestDescription).NotEmpty().Length(0, 50); } } Using the When() method appended to my custom rules also causes a null reference exception in the Fluent Validation code. I apologize for the confusion.