Quantcast
Channel: Fluent Validation for .NET
Viewing all articles
Browse latest Browse all 1917

Commented Unassigned: SetValidator with When not work valid in MVC 4 [7142]

$
0
0
I have models and validators:

```
[Validator(typeof(AdressValidator))]
public class Adress {
public string PostalCode { get; set; }
public string Street { get; set; }
}

[Validator(typeof(PersonValidator))]
public class Person
{
public Adress Adress { get; set; }
public bool IsAdress2 { get; set; }
public Adress Adress2 { get; set; }
}

public class AdressValidator : AbstractValidator<Adress> {
public AdressValidator() {
RuleFor(p => p.PostalCode).NotEmpty();
RuleFor(p => p.Street).NotEmpty();
}
}

public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(p => p.Adress).SetValidator(new AdressValidator());
RuleFor(p => p.Adress2).SetValidator(new AdressValidator()).When(p=>p.IsAdress2);
}
}
```

And controlers:
```
public class HomeController : Controller
{
//
// GET: /Home/

public ActionResult Index() {
Person person = new Person() {
Adress = new Adress() {
PostalCode = "12-100",
Street = "Street 13"
},
IsAdress2 = false,
Adress2 = new Adress()
};

return View(person);
}

[HttpPost]
public ActionResult Index(Person person)
{
if (ModelState.IsValid) {
return RedirectToAction("OK");
}
return View(person);
}

public ActionResult Ok() {
return View();
}
}
```

Adress2 is always validated.

In Attachments is solution without lib and packages.
Comments: Hi So the issue here is that you're using the [Validator] attribute incorrectly. In your code, you're using both SetValidator and the ValidatorAttribute, which will cause each Address property to be validated twice. When you use the [Validator] attribute, this tells MVC to instantiate an AddressValidator *every time it encouters a property of type Address*. In your case, this *isn't* what you want, because you're also explicitly defining the AddressValidator in the SetValidator call. So MVC executes validation for each Address property twice: - When MVC's model binding process encouters the Address property, it will create an execute an AddressValidator, completely independently of the PersonValidator (so the .When clause is completely ignored, as the PersonValidator hasn't event been invoked yet) - MVC will then ask FluentValidation to create and invoke the PersonValidator, which this time will take the When clause into account. Solution: Remove the [Validator] attribute from the Address class. You only want to put the attribute on the class that is the *top level* in the hierarchy, (in this case, Person).

Viewing all articles
Browse latest Browse all 1917

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>