这两个bug都是查了挺久才查到的,随手记是个好习惯。
1.public static CultureInfo GetCultureInfo(string name); 方法,传参错误时,某些操作系统环境会不抛异常。(用于ValidationAttribute校验参数)
本机环境是win10 x64 测试环境是linux,.net core 2.0
修改方案:
ValidCultureNames = CultureInfo.GetCultures(CultureTypes.AllCultures) .Where(t => !string.IsNullOrEmpty(t.Name)).Select(t => t.Name.ToLower()).ToList(); public override bool IsValid(object value) { var cultureInfo = value as string; if (string.IsNullOrEmpty(cultureInfo)) { ErrorMessage = ValidationError.CultureInfoIsNull.ToMultiLanguageString(); return false; } if (Q9LanguageExtendtions.ValidCultureNames.Contains(cultureInfo.ToLower())) { return true; } ErrorMessage = ValidationError.CultureInfoParseError.ToMultiLanguageString(); return false; }
2.public static bool TryValidateObject(object instance,ValidationContext validationContext,ICollection<ValidationResult> validationResults,bool validateAllProperties);方法在多线程下可能抛出NullReferenceException
源码分析过,抛错行应该是
protected string ErrorMessageString { get { this.SetupResourceAccessor(); return this._errorMessageResourceAccessor(); } }
中_errorMessageResourceAccessor = null导致的NullReferenceException。
修改方案:重写FormatErrorMessage
public override string FormatErrorMessage(string name) { return ErrorMessage; }
认真查了问题后发现:
多个tryValidateObject方法在验证多个dto时,构造方法只调用了一次,即用的同一个实例,导致并发情况下会出现多处的ErrorMessage set时修改了Accessor为null。
解决方案:
重新阅读官方文档后发现:
1.官方文档上写的应重写IsValid(Object value)
2.但是源码中写的是重写protected override ValidationResult IsValid(object value, ValidationContext validationContext)
3.官方实例也是用的重写protected override ValidationResult IsValid(object value, ValidationContext validationContext)
于是我重写了该方法后,再次并发测试,终于不再抛出该异常。
问题解决。