ASP.NET MVC表单提交默认是否验证?自定义日期验证失效及提示来源咨询
嘿,这两个问题我刚好有实操经验,给你拆解清楚:
1. ASP.NET MVC提交表单时默认是否执行验证?
答案是肯定的,默认会执行双层验证机制:
- 客户端验证:ASP.NET MVC的默认模板会自动引入jQuery和jQuery Validate插件,框架会根据模型上的数据注解(比如
[Required]、[EmailAddress]这类)自动生成客户端验证规则,用户提交表单前就会在浏览器端拦截无效输入,不用额外写JS代码。 - 服务器端验证:就算用户禁用了JS绕过客户端验证,表单提交到Action方法时,框架会自动对传入的强类型模型做校验。你只需要在Action里判断
ModelState.IsValid就能拿到验证结果——这个过程是自动触发的,不需要手动调用验证方法。
2. 自定义日期验证未生效&默认英文提示的问题
先搞懂提示来源
你看到的“字符串对对象属性无效”这个英文提示,是.NET框架在模型绑定阶段抛出的类型转换错误。举个例子:当你提交非闰年的02/29/2017时,框架尝试把这个字符串转换成DateTime类型,但转换失败了,这时候模型对象都没成功创建出来,你的自定义验证逻辑根本没机会执行——因为验证是在模型绑定完成后才会触发的。
解决思路&具体方法
要同时解决“自定义验证生效”和“替换葡萄牙语提示”的问题,有几个可行方案:
方案1:自定义日期模型绑定器(最推荐)
自己写一个绑定器,在模型绑定过程中直接处理日期校验和错误提示,这样能跳过框架默认的错误提示,同时让自定义逻辑提前生效:
public class CustomDateTimeBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var inputValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (inputValue == null) return null; string dateInput = inputValue.AttemptedValue.Trim(); if (string.IsNullOrEmpty(dateInput)) return null; // 先尝试解析日期 if (!DateTime.TryParse(dateInput, out DateTime parsedDate)) { // 替换成葡萄牙语提示 bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Data inválida"); return null; } // 加入你的自定义校验:非闰年不能有2月29日 bool isLeapYear = DateTime.IsLeapYear(parsedDate.Year); if (parsedDate.Month == 2 && parsedDate.Day == 29 && !isLeapYear) { bindingContext.ModelState.AddModelError(bindingContext.ModelName, "29 de fevereiro não é válido para anos não bissextos"); return null; } return parsedDate; } }
然后在Global.asax(或者Startup类,取决于你的MVC版本)里注册这个绑定器:
protected void Application_Start() { // 其他初始化代码... ModelBinders.Binders.Add(typeof(DateTime), new CustomDateTimeBinder()); }
方案2:用Nullable配合自定义验证属性
如果你的日期字段允许为空,可以把模型属性改成DateTime?(可空DateTime):
// 这里的CustomDateValidation是你自己实现的验证属性 [CustomDateValidation(ErrorMessage = "Data inválida: 29 de fevereiro não é permitido em anos não bissextos")] public DateTime? EventDate { get; set; }
这样模型绑定不会因为无效日期失败(只会把属性设为null),你的自定义验证属性就能正常执行,同时可以直接在ErrorMessage里写葡萄牙语提示。
方案3:直接替换框架默认错误消息
如果你只是想换掉那个英文提示,不想改绑定逻辑,可以用资源文件来覆盖默认错误:
- 新建一个资源文件(比如
Resources.resx),添加键值对:PropertyValueInvalid= "Data inválida" - 在
Global.asax里指定资源文件:
protected void Application_Start() { // 其他初始化代码... DefaultModelBinder.ResourceClassKey = "Resources"; }
这样框架抛出的类型转换错误就会自动用你资源文件里的葡萄牙语提示了。
内容的提问来源于stack exchange,提问作者Diego Alves
相关产品推荐
相关产品推荐

