1

ASP.NET MVC3/Razor newbie question:

I am setting up a model with custom validation. While the properties that I decorate with things like [Required] and [RegularExpression(...)] are performing as expected, I'm finding that the custom validation is not working. I made my model implement IValidatableObject, and I can hit a breakpoint inside the Validate() method and watch the method doing a yield return new ValidationResult(...); - but the form nonetheless gets posted.

Is there some secret switch that I'm missing?

1
  • 2
    you mean client side, right ? If yes, then have you included the validation scripts in the view Commented Jan 6, 2012 at 13:10

2 Answers 2

2

If you are talking about server side validation, do you have the ModelState.Isvalid check? http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

Sign up to request clarification or add additional context in comments.

3 Comments

This isn't an answer, this is a question. Questions would be better in the comments section of the question.
@Dangerous - fair comment, but +1 anyway for pointing out what I was missing.
@Dangerous I put it here because I didn't see the option to comment on the question.
1

The form will be posted when you use IValidatableObject to validate model properties. As Joeri Jans says, you can still prevent this and return the page to the user during your action method:

public ActionResult MyAction(MyModel model)
{
    if (ModelState.IsValid)
    {
        // code to perform action when input is valid
        return [return something]
    }
    return View(model); // re-display form because ModelState.IsValid == false
}

If you want your custom validation to prevent the form from being posted, you need to validate on the client. The easiest way to do this is with the RemoteAttribute.

public class MyModel
{
    [Remote("MyValidateAction", "MyController", HttpMethod = "POST")]
    public string MyProperty { get; set; }
}

You can still keep your code in IValidatableObject, and validate it from an action method like so:

[HttpPost]
public virtual JsonResult MyValidateAction(string myProperty)
{
    var model = new MyModel{ MyProperty = myProperty, };
    var results = new List<ValidationResult>();
    var isValid = Validator.TryValidateObject(model, 
        new ValidationContext(model, null, null), results, true);
    return isValid
        ? Json(true)
        : Json(results[0].ErrorMessage);
}

The above action method does virtually the same thing as the default model binder. It constructs an instance of your viewmodel, then validates it. All validation rules will be checked, including your IValidatableObject code. If you need to send more properties to the action method for the construction of your viewmodel, you can do so with the AdditionalFields property of the RemoteAttribute.

Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.