ModelState.IsValid vs IValidateableObject in MVC3

好久不见. 提交于 2019-12-05 11:46:03

问题


so according to Gu IValidatableObject.Validate() should get called when a controller validates it's model (i.e. before ModelState.IsValid) however simply making the model implement IValidatableObject doesn't seem to work, because Validate(..) doesn't get called.

Anyone know if there is something else I have to wire up to get this to work?

EDIT:

Here is the code as requested.

public class LoginModel : IValidatableObject
{
    [Required]
    [Description("Email Address")]
    public string Email { get; set; }

    [Required]
    [Description("Password")]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DisplayName("Remember Me")]
    public bool RememberMe { get; set; }

    public int UserPk { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var result = DataContext.Fetch( db => {

            var user = db.Users.FirstOrDefault(u => u.Email == Email);

            if (user == null) return new ValidationResult("That email address doesn't exist."); 
            if (user.Password != User.CreateHash(Password, user.Salt)) return new ValidationResult("The password supplied is incorrect.");

            UserPk = user.UserPk;
            return null;
        });

        return new List<ValidationResult>(){ result };
    }
}

The action. ( I don't do anything special in the Controller...)

[HttpPost]
public ActionResult Login(LoginModel model)
{
    if (ModelState.IsValid)
    {
        FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
        return Redirect(Request.UrlReferrer.AbsolutePath);
    }

    if (ControllerContext.IsChildAction || Request.IsAjaxRequest())
        return View("LoginForm", model);

    return View(model);
}

I set a break point on the first line of LoginModel.Validate() and it doesn't seem to get hit.


回答1:


There isn't anything more than that you just have to add it to the model you're validating. Here's an example of validation

public class User : IValidatableObject {
    public Int32 UserID { get; set; }
    public string Name { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        //do your validation

        return new List<ValidationResult>();
    }
}

And your controller would use this model

public ActionResult Edit(User user) {
    if (ModelState.IsValid) {
    }
}

Hope this helps. Other requirements are .net 4 and data annotations - which you obviously need jsut for ivalidatableobject. Post any issues and we'll see if we can't resolve them - like post your model and your controller...you might be missing something.




回答2:


Validation using the DefaultModelBinder is a two stage process. First, Data Annotations are validated. Then (and only if the data annotations validation resulted in zero errors), IValidatableObject.Validate() is called. This all takes place automatically when your post action has a viewmodel parameter. ModelState.IsValid doesn't do anything as such. Rather it just reports whether any item in the ModelState collection has non-empty ModelErrorCollection.



来源:https://stackoverflow.com/questions/3744408/modelstate-isvalid-vs-ivalidateableobject-in-mvc3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!