MVC3 中的 ModelState.IsValid 与 IValidateableObject
所以根据 Gu IValidatableObject.Validate()
应该在控制器验证其模型时被调用(即在 ModelState.IsValid
之前),但是只需使模型实现 IValidatableObject
似乎不起作用,因为 Validate(..)
没有被调用。
有人知道我是否还需要连接其他东西才能使其正常工作吗?
编辑:
这是所要求的代码。
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 };
}
}
行动。 (我没有在控制器中做任何特殊的事情...)
[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);
}
我在 LoginModel.Validate()
的第一行设置了一个断点,它似乎没有被击中。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 DefaultModelBinder 进行验证是一个两阶段的过程。首先,验证数据注释。然后(并且仅当数据注释验证导致零错误时),调用
IValidatableObject.Validate()
。当您的后期操作具有视图模型参数时,这一切都会自动发生。ModelState.IsValid
不会执行任何此类操作。相反,它只是报告ModelState
集合中的任何项目是否具有非空ModelErrorCollection
。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 theModelState
collection has non-emptyModelErrorCollection
.您只需将其添加到您正在验证的模型中即可。这是一个验证示例
,您的控制器将使用此模型
希望这会有所帮助。其他要求是 .net 4 和数据注释 - 显然您需要 ivalidatableobject。发布任何问题,我们会看看是否无法解决它们 - 例如发布您的模型和控制器......您可能会丢失一些东西。
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
And your controller would use this model
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.