这两个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)

记.net 遇到的几个bug-LMLPHP

2.但是源码中写的是重写protected override ValidationResult IsValid(object value, ValidationContext validationContext)

记.net 遇到的几个bug-LMLPHP

3.官方实例也是用的重写protected override ValidationResult IsValid(object value, ValidationContext validationContext)

记.net 遇到的几个bug-LMLPHP

于是我重写了该方法后,再次并发测试,终于不再抛出该异常。

问题解决。

05-11 15:39
查看更多