在.net Mvc开发时我们一般都会选择自带的验证机制。
我们定义一个model
public class ContainerModel {
[Display(Name = "流水号")]
public long Id { get; set; }
[Display(Name = "委托业务流水号")]
[Required(ErrorMessage = "委托业务流水号不能为空")]
public long ConsignId { get; set; }
[Display(Name = "所属人")]
public long? OwnerId { get; set; }
}
控制器,用ModelState.IsValid进行验证,ExpendErrors是一个拓展方法,获取验证失败的字段
public ActionResult Create(ContainerModel model)
{
if (ModelState.IsValid) {
//...
} else {
log.Warn("失败,数据不完整-" + this.ExpendErrors());
return Json(...);
}
}
}
我们都知道,当从前端页面传入参数时,ConsignId字段是必须传的,但是 Id和OwnerId呢?
OwnerId是可空类型,前端当然可以不传参数,或者传一个空值的参数也可以,验证通过。
Id是不可空int类型,我们可以测试一下:
$.ajax({
type: "Post",
url: "Create",
data: {
Id:0,
ConsignId:10,
OwnerId:1,
},
success: function (result) {
}
}, "json");
OK,验证通过
$.ajax({ type: "Post", url: "Create", data: { ConsignId:10, OwnerId:1, }, success: function (result) { } }, "json");
OK,验证也通过
$.ajax({ type: "Post", url: "Create", data: { Id:, ConsignId:10, OwnerId:1, }, success: function (result) { } }, "json");
这时候就不能通过了,监控ExpendErrors得到Id字段是必须的,断点到控制器Create方法,看到传过来的Model.Id=0也是有值的,这就奇怪了,明明有值的,也没设置Required验证,为什么就通不过了呢?
原来,是我没有理解验证机制的原理,验证机制是发生在前端参数转化为后端model属性时候发生的,也就是执行目标Action方法之前,model的Id为不可空的Int类型,而参数传递了一个空值,所以验证不同过。解决办法就是:要么不传该参数,要传就传有初始化值的参数。