C#中使用DataAnnotations验证时如何避免重复错误消息?
解决DataAnnotations中重复错误消息的替代方案
因为属性的参数必须是常量表达式,所以你没法直接把方法调用作为ErrorMessage的参数。不过有几种可行的方式避免重复写错误消息,同时满足你的动态消息需求:
方案1:自定义ValidationAttribute(最适合你的场景)
这种方式能完全控制验证逻辑和错误消息生成,还能直接访问实例的其他属性(比如Id):
public class MustBeGreaterThanZeroAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value is double num && num <= double.Epsilon) { // 获取实例的Id值 var idProperty = validationContext.ObjectType.GetProperty("Id"); var idValue = idProperty?.GetValue(validationContext.ObjectInstance)?.ToString() ?? "unknown"; // 获取类名和当前字段名 var className = validationContext.ObjectType.Name; var fieldName = validationContext.MemberName; var errorMessage = string.Format("The value {0} assigned to the field {1} in {2} ID {3} must be greater than ZERO.", value, fieldName, className, idValue); return new ValidationResult(errorMessage); } return ValidationResult.Success; } }
在实体类中直接使用这个自定义属性即可,不需要重复写错误消息:
public class Foo { public string Id { get; set; } [MustBeGreaterThanZero] public double Bar { get; set; } }
方案2:用常量类集中管理消息模板
如果只是想避免重复写相同的消息文本,可以把模板放在常量类里,再结合自定义属性使用(单独用内置属性的话没法填充实例动态数据):
public static class ErrorMessageTemplates { public const string MustBeGreaterThanZero = "The value {0} assigned to the field {1} in {2} ID {3} must be greater than ZERO."; }
然后在自定义Attribute里直接引用这个常量来格式化消息,这样所有使用该属性的地方都会复用同一个模板。
方案3:继承内置Attribute扩展消息(适合简单场景)
如果不想完全自定义验证逻辑,也可以继承内置的RangeAttribute,重写消息格式化逻辑,但这种方式没法直接获取实例的Id等动态数据,适合不需要实例信息的场景:
public class RangeGreaterThanZeroAttribute : RangeAttribute { public RangeGreaterThanZeroAttribute() : base(double.Epsilon, double.MaxValue) { ErrorMessage = ErrorMessageTemplates.MustBeGreaterThanZero; } }
内容的提问来源于stack exchange,提问作者Fabiano Augusto
相关产品推荐
相关产品推荐

