You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:51:02