Custom Data Annotations IsValid is never invoked. (ASP.NET MVC 2 .NET 4)
Asked Answered
C

2

8

I have a custom Data Validation Attribute I've created to make sure the passwords a user inputs are the same, but IsValid is never invoked.

Custom attribute:

public class IsSameAsAttribute : ValidationAttribute
{
    public String TargetProperty { get; set; }
    private readonly object _typeId = new object();

    public IsSameAsAttribute(string targetProperty)
    {
        TargetProperty = targetProperty;
    }

    public override bool IsValid(object value)
    {
        return false;
        //Type objectType = value.GetType();
        //bool isValid = false;

        //PropertyInfo[] neededProperties =
        //    objectType.GetProperties().Where(propertyInfo => propertyInfo.Name == TargetProperty).ToArray();

        //return isValid;
    }

    public override object TypeId
    {
        get { return _typeId; }
    }
}

Data model it is applied to:

public class RegistrationData
{
    [Required(ErrorMessage = "First Name Required")]
    [StringLength(100, ErrorMessage = "First Name must be 100 characters or less.")]
    public String FirstName { get; set;}

    [Required(ErrorMessage = "Last Name Required")]
    [StringLength(100, ErrorMessage = "Last Name must be 100 characters or less.")]
    public String LastName { get; set; }

    [Required(ErrorMessage = "Email is Required")]
    [StringLength(200, ErrorMessage = "Email must be 200 characters or less.")]
    [RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Valid Email Address is required.")]
    public String Email { get; set; }

    [Required(ErrorMessage = "Password is required")]
    public String Password { get; set; }

    [IsSameAs("Password")]
    public String PasswordRepeat { get; set; }

    [Required(ErrorMessage = "Division is required")]
    public String Division { get; set; }

}

And the Controller where it is called from:

[HttpPost]
public ActionResult ValidationDemo(RegistrationData model)
{
    if (ModelState.IsValid)
    {
        return Redirect("/");
    }

    return View(model);
}

All the "out of the box" validations operate correctly, it is just my custom one that isn't being invoked. In doing debugging I find that it is instantiated as the constructor is called, but a break-point set on IsValid is never hit.

What is going on and how do I fix it?

UPDATE

All right I fiddled some and if I call TryUpdateModel(model) in my controller it finally invokes IsValid. So this implies to me that my custom attribute isn't getting "registered" with whatever runs the validations in MVC 2. Is there a way to address this?

[HttpPost]
public ActionResult ValidationDemo(RegistrationData model)
{
    TryValidateModel(model);  // <--- *** Added this line and it "works"

    if (ModelState.IsValid)
    {
        return Redirect("/");
    }

    return View(model);
}
Cloninger answered 29/6, 2010 at 21:33 Comment(1)
Have you registered an adapter to use in conjunction with your custom validation attribute with DataAnnotationsModelValidatorProvider.RegisterAdapter?Nanji
U
3

I'm seeing a similar/same/related issue with MVC2 - the class-level validation is called only if all the properties validate correctly.

So multiple properties may fail, and all validation messages are added to the model state (and displayed on the client.) But the class-level validation message isn't among them; the IsValid on these only gets called if properties pass. Bit a a bummer from a usability standpoint but it works.

I am not calling TryValidateModel().

Unpaged answered 10/5, 2011 at 20:29 Comment(0)
M
0

Have you tried to fill in all other fields so all the out-of-the-box validation are satisfied, and see if your custom validation is triggered? If the client validation are not satisfied, the form will be prevented from posting back and thus your server-side custom validation will not be trigerred,

To have your custom validation attribute work on the client side, some additional work has to be made.

Read up on Phil's excellent post on validation here: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

Moshe answered 29/6, 2010 at 22:15 Comment(2)
At the moment I'm not doing client side validation to try and get this to work. At least I don't think I am. Hmm I should maybe check that. However, I was running break points on the ModelState.IsValid in the controller and the Model's error collection never had error states for my custom validation items. And yes, before my update, I filled out the form and it still didn't trigger the custom validation attribute. :(Cloninger
hmm, so my assumption was wrong, and this is truely strange. Can you post code for you [HttpGet] method and the view?Moshe

© 2022 - 2024 — McMap. All rights reserved.