ASP.NET验证:如何为DataAnnotation错误消息使用参数
解决DataAnnotations验证消息中传入用户输入值的问题
你提到的这个情况确实是内置DataAnnotations验证属性的一个限制——默认情况下,像Required、RegularExpression这类属性在使用资源文件时,只会把字段的DisplayName作为{0}填充到错误消息里,没办法直接传入用户的实际输入值。不过我们有两种靠谱的解决方案:
方案一:自定义验证属性(推荐)
最优雅的方式是自定义一个继承自目标验证属性的类,重写验证逻辑来手动控制错误消息的参数填充。以你用到的RegularExpressionAttribute为例:
public class CustomRegularExpressionAttribute : RegularExpressionAttribute { public CustomRegularExpressionAttribute(string pattern) : base(pattern) { // 绑定资源文件配置 ErrorMessageResourceType = typeof(SiteResources); ErrorMessageResourceName = "InvalidField"; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var baseResult = base.IsValid(value, validationContext); if (baseResult != ValidationResult.Success) { // 获取字段显示名和用户输入值 var displayName = validationContext.DisplayName; var userInput = value?.ToString() ?? string.Empty; // 用资源字符串和参数生成最终错误消息 var formattedMsg = string.Format(SiteResources.InvalidField, userInput, displayName); return new ValidationResult(formattedMsg); } return baseResult; } }
然后在模型中替换原来的验证属性即可:
[DisplayName("Phone Number")] [CustomRegularExpression(@"^\+?[\s\d]*$")] public string PhoneNumber { get; set; }
这样当验证失败时,错误消息里的{0}会被用户输入的实际值替换,{1}会被字段的DisplayName替换,完全匹配你的需求。
方案二:手动修改ModelState错误消息(备选)
如果你不想自定义属性,可以在控制器的验证环节,手动遍历ModelState的错误并替换占位符。示例代码如下:
[HttpPost] public IActionResult Submit(YourModel model) { if (!ModelState.IsValid) { foreach (var key in ModelState.Keys) { var property = model.GetType().GetProperty(key); if (property == null) continue; var fieldDisplayName = property.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName ?? key; var userInput = property.GetValue(model)?.ToString() ?? string.Empty; var errors = ModelState[key].Errors; for (int i = 0; i < errors.Count; i++) { var msg = errors[i].ErrorMessage; if (msg.Contains("{0}") && msg.Contains("{1}")) { errors[i].ErrorMessage = string.Format(msg, userInput, fieldDisplayName); } } } return View(model); } // 后续业务逻辑 }
这个方法无需修改验证属性,但缺点是需要在每个需要的控制器方法中重复处理,代码冗余度较高,适合临时场景或小型项目使用。
内容的提问来源于stack exchange,提问作者user1913944
相关产品推荐
相关产品推荐

