记.net 遇到的几个bug

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

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

问题解决。

原文地址:https://www.cnblogs.com/sylvialucy/p/10796087.html