using System.Globalization; using System.Reflection; namespace YLErp.Modules.SuperviseReportModule.SAC.Common { #region CheckAttrbute /// /// 检查字段属性基类 /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] public abstract class BaseCheckAttribute : Attribute { /// /// 是否必填 /// 默认为true /// public bool Required { get; set; } = true; /// /// 处理逻辑名称 /// 该值主要为的派生类提供指定处理逻辑时的绑定名称,如果不需要指定,则该字段不应填写 /// 该值不为Null时,则应在的派生类中字段中指定,否则永远不会被执行 /// public string CheckHandleName { get; set; } /// /// 是否需要修改值 /// public bool UseChangeValue { get; protected set; } /// /// 修改后的值 /// public object ChangedValue { get; protected set; } /// /// 错误提示 /// public abstract string ErrMsg { get; set; } public abstract bool Execute(object value); } /// /// 检查字符串字段属性基类 /// public abstract class BaseCheckStringAttribute : BaseCheckAttribute { /// /// Null或空白字符是否通过检查 /// 仅Required=true时有效 /// 默认为和Required一致 /// public bool IgnoreNullOrEmpty { get; set; } = false; public override bool Execute(object value) { var state = false; var text = (value?.ToString()) ?? ""; if (text.Length == 0) { state = !Required || IgnoreNullOrEmpty; } else { state = Execute(value?.ToString()); } if (!state) { ErrMsg = GenerateErrMsg(value?.ToString()); } return state; } protected abstract string GenerateErrMsg(string value); protected abstract bool Execute(string value); } /// /// 检查字符串长度 /// 字符串长度是否等于预设值 /// public sealed class CheckStringLengthAttribute : BaseCheckStringAttribute { /// /// 字符串长度 /// public int Length { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,长度应为{Length} /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且长度应为{Length}"; _errMsg = "值不应为空,且长度应为{Length}"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { return (value ?? "").Length == Length; } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{Length}", Length.ToString()); } } /// /// 检查字符串最大长度 /// 字符串长度是否超过预设值 /// public sealed class CheckStringMaxLengthAttribute : BaseCheckStringAttribute { /// /// 字符串最大长度 /// public int MaxLength { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,最大长度不应超过{MaxLength} /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且最大长度不应超过{MaxLength}"; _errMsg = "值不应为空,且最大长度不应超过{MaxLength}"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { return (value ?? "").Length <= MaxLength; } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{MaxLength}", MaxLength.ToString()); } } /// /// 检查字符串最小长度 /// 字符串长度是否低于预设值 /// public sealed class CheckStringMinLengthAttribute : BaseCheckStringAttribute { /// /// 字符串最小长度 /// public int MinLength { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,长度不应小于{MinLength} /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且长度不应小于{MinLength}"; _errMsg = "值不应为空,且长度不应小于{MinLength}"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { return (value ?? "").Length >= MinLength; } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{MinLength}", MinLength.ToString()); } } /// /// 检查字符串结尾 /// 检查字符串是否以预设值结尾 /// public sealed class CheckStringEndsWithAttribute : BaseCheckStringAttribute { /// /// 指定字符串结尾部分 /// public string EndsWithString { get; set; } /// /// 多选模式 /// 该字段为true时,将使用分割后,进行匹配 /// public bool Multiple { get; set; } /// /// 多条件分隔符 /// public string SplitStr { get; set; } = "|"; /// /// 如字符串为英文字母,是否忽略大小写 /// 默认为:true /// public bool IgnoreCase { get; set; } = true; private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,内容应以{EndsWithString}结尾 /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且内容应以{EndsWithString}结尾"; _errMsg = "值不应为空,且内容应以{EndsWithString}结尾"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { var match = false; if (Multiple) { var split = EndsWithString.Split(SplitStr.ToCharArray()); foreach (var item in split) { match = (value ?? "").EndsWith(item, IgnoreCase, CultureInfo.CurrentCulture); if (match) { break; } } } else { match = (value ?? "").EndsWith(EndsWithString, IgnoreCase, CultureInfo.CurrentCulture); } return match; } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{EndsWithString}", EndsWithString); } } /// /// 检查字符串是否为指定格式的DateTime字符串 /// public sealed class CheckStringIsDateTimeFormatAttribute : BaseCheckStringAttribute { /// /// DateTime类型支持的格式化字符 /// 默认为:yyyy-MM-dd /// public string FormatString { get; set; } = "yyyy-MM-dd"; private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,不匹配{FormatString}格式 /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,不匹配{FormatString}格式"; _errMsg = "不匹配{FormatString}格式"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { var result = true; try { result = DateTime.TryParseExact(value ?? "", FormatString, CultureInfo.CurrentCulture, DateTimeStyles.None, out _); if (!result) { result = DateTime.TryParse(value ?? "", out var temp); if (result) { UseChangeValue = true; ChangedValue = temp.ToString(FormatString); } } } catch { result = false; } return result; } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{FormatString}", FormatString); } } /// /// 检查字符串是否为数字或百分数,长度在指定范围内,可选是否检查值的合法区间 /// public sealed class CheckStringIntOrPercentRangeAttribute : BaseCheckStringAttribute { /// /// 值为数字时小数点前最大长度 /// public int BeforePointMaxLength_Number { get; set; } /// /// 值为数字时小数点后最大长度 /// public int AfterPointMaxLength_Number { get; set; } /// /// 值为数字时最大值 /// 可选,不设置则不检查 /// public double MaxValue_Number { get; set; } = double.NaN; /// /// 值为数字时最小值 /// 可选,不设置则不检查 /// public double MinValue_Number { get; set; } = double.NaN; /// /// 值为百分数时小数点前最大长度 /// public int BeforePointMaxLength_Percent { get; set; } /// /// 值为百分数时小数点后最大长度 /// public int AfterPointMaxLength_Percent { get; set; } /// /// 值为百分数时最大值 /// 可选,不设置则不检查 /// public double MaxValue_Percent { get; set; } = double.NaN; /// /// 值为百分数时最小值 /// 可选,不设置则不检查 /// public double MinValue_Percent { get; set; } = double.NaN; private string _errMsg; /// /// 错误提示 /// 默认为: /// {fieldName}={fieldValue}不合法,保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}],取值区间为[>{MinValue},<{MaxValue}] /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; _errMsg = "值应为数字,且保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; double minValue, maxValue; if (isPercent) { minValue = MinValue_Percent; maxValue = MaxValue_Percent; } else { minValue = MinValue_Number; maxValue = MaxValue_Number; } var msgArr = new List(); if (!double.IsNaN(minValue)) { msgArr.Add(">={MinValue}"); } if (!double.IsNaN(maxValue)) { msgArr.Add("<={MaxValue}"); } if (msgArr.Count > 0) { _errMsg += $",取值范围为[{string.Join(",", msgArr)}]"; } } return _errMsg; } set { _errMsg = value; } } private bool isPercent; protected override bool Execute(string value) { int beforePointMaxLength, afterPointMaxLength; double maxValue, minValue; isPercent = isPercent = value != null && value.EndsWith("%"); if (isPercent) { value = value.Remove(value.Length - 1); beforePointMaxLength = BeforePointMaxLength_Percent; afterPointMaxLength = AfterPointMaxLength_Percent; maxValue = MaxValue_Percent; minValue = MinValue_Percent; } else { beforePointMaxLength = BeforePointMaxLength_Number; afterPointMaxLength = AfterPointMaxLength_Number; maxValue = MaxValue_Number; minValue = MinValue_Number; } if (!double.TryParse(value, out var temp)) { return false; } var part = (value ?? "").Split('.'); if (part.Length > 2) { return false; } if (part[0].Length > beforePointMaxLength) { return false; } if (!double.IsNaN(maxValue) && temp > maxValue) { return false; } if (!double.IsNaN(minValue) && temp < minValue) { return false; } if (part.Length > 1 && part[1].Length > afterPointMaxLength) { UseChangeValue = true; string sufix = "0.".PadRight(afterPointMaxLength + 2, '0'); UseChangeValue = true; ChangedValue = temp.ToString(sufix) + (isPercent ? "%" : ""); return true; } return true; } protected override string GenerateErrMsg(string value) { int beforePointMaxLength, afterPointMaxLength; double maxValue, minValue; isPercent = isPercent = value != null && value.EndsWith("%"); if (isPercent) { value = value.Remove(value.Length - 2); beforePointMaxLength = BeforePointMaxLength_Percent; afterPointMaxLength = AfterPointMaxLength_Percent; maxValue = MaxValue_Percent; minValue = MinValue_Percent; } else { beforePointMaxLength = BeforePointMaxLength_Number; afterPointMaxLength = AfterPointMaxLength_Number; maxValue = MaxValue_Number; minValue = MinValue_Number; } return ErrMsg .Replace("{fieldValue}", value) .Replace("{BeforePointMaxLength}", beforePointMaxLength.ToString()) .Replace("{AfterPointMaxLength}", afterPointMaxLength.ToString()) .Replace("{MinValue}", minValue.ToString()) .Replace("{MaxValue}", maxValue.ToString()); } } /// /// 检查字符串是否为数字,长度在指定范围内,可选是否检查值的合法区间 /// public sealed class CheckStringIntMaxLengthAttribute : BaseCheckStringAttribute { /// /// 小数点前最大长度 /// public int BeforePointMaxLength { get; set; } /// /// 小数点后最大长度 /// public int AfterPointMaxLength { get; set; } /// /// 最大值 /// 可选,不设置则不检查 /// public double MaxValue { get; set; } = double.NaN; /// /// 最小值 /// 可选,不设置则不检查 /// public double MinValue { get; set; } = double.NaN; private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}],取值范围为[>{MinValue},<{MaxValue}] /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; _errMsg = "值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; var msgArr = new List(); if (!double.IsNaN(MinValue)) { msgArr.Add(">={MinValue}"); } if (!double.IsNaN(MaxValue)) { msgArr.Add("<={MaxValue}"); } if (msgArr.Count > 0) { _errMsg += $",取值范围为[{string.Join(",", msgArr)}]"; } } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { if (!double.TryParse(value, out var temp)) { return false; } var part = (value ?? "").Split('.'); if (part.Length > 2) { return false; } if (part[0].Length > BeforePointMaxLength) { return false; } var state = true; if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointMaxLength)) { UseChangeValue = true; var sufix = "0.".PadRight(AfterPointMaxLength + 2, '0'); UseChangeValue = true; ChangedValue = temp.ToString(sufix); state = true; } if (!double.IsNaN(MinValue) && temp < MinValue) { state = false; } if (!double.IsNaN(MaxValue) && temp > MaxValue) { state = false; } return state; } protected override string GenerateErrMsg(string value) { return ErrMsg .Replace("{fieldValue}", value) .Replace("{BeforePointMaxLength}", BeforePointMaxLength.ToString()) .Replace("{AfterPointMaxLength}", AfterPointMaxLength.ToString()) .Replace("{MinValue}", MinValue.ToString()) .Replace("{MaxValue}", MaxValue.ToString()); } } /// /// 检查字符串是否为数字,长度在指定范围内(小数长度必须和预设值相等),可选是否检查值的合法区间 /// public sealed class CheckStringIntLengthAttribute : BaseCheckStringAttribute { /// /// 小数点前最大长度 /// public int BeforePointMaxLength { get; set; } /// /// 小数点后长度 /// 小数位必须与该值相等,否则应使用 /// public int AfterPointLength { get; set; } /// /// 最大值 /// 可选,不设置则不检查 /// public double MaxValue { get; set; } = double.NaN; /// /// 最小值 /// 可选,不设置则不检查 /// public double MinValue { get; set; } = double.NaN; private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,保留位数必须为{BeforePointMaxLength},{AfterPointLength},取值范围为[>{MinValue},<{MaxValue}] /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]"; _errMsg = "值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]"; var msgArr = new List(); if (!double.IsNaN(MinValue)) { msgArr.Add(">={MinValue}"); } if (!double.IsNaN(MaxValue)) { msgArr.Add("<={MaxValue}"); } if (msgArr.Count > 0) { _errMsg += $",取值范围为[{string.Join(",", msgArr)}]"; } } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { if (!double.TryParse(value, out var temp)) { return false; } if (!double.IsNaN(MinValue) && temp < MinValue) { return false; } if (!double.IsNaN(MaxValue) && temp > MaxValue) { return false; } var part = (value ?? "").Split('.'); if (part[0].Length > BeforePointMaxLength) { return false; } if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointLength)) { var sufix = "0.".PadRight(AfterPointLength + 2, '0'); UseChangeValue = true; ChangedValue = temp.ToString(sufix); return true; } return true; } protected override string GenerateErrMsg(string value) { return ErrMsg .Replace("{fieldValue}", value) .Replace("{BeforePointMaxLength}", BeforePointMaxLength.ToString()) .Replace("{AfterPointLength}", AfterPointLength.ToString()) .Replace("{MinValue}", MinValue.ToString()) .Replace("{MaxValue}", MaxValue.ToString()); } } /// /// 检查IEnumerable基类属性基类 /// public abstract class BaseCheckIEnumerableTAttribute : BaseCheckAttribute { public override bool Execute(object value) { var state = false; var objs = value as IEnumerable; //if (objs != null) //{ state = Execute(objs); //} if (!state) { ErrMsg = GenerateErrMsg(objs); } return state; } protected abstract string GenerateErrMsg(IEnumerable value); protected abstract bool Execute(IEnumerable value); } /// /// 检查列表最小数量 /// public sealed class CheckIEnumerableTMinCountAttribute : BaseCheckIEnumerableTAttribute { /// /// 列表数量 /// public int MinCount { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}.Length={fieldValue}不合法,应大于{MinCount} /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}.Length={fieldValue}不合法,数量应大于{MinCount}"; _errMsg = "列表长度={fieldValue}不合法,应大于{MinCount}"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(IEnumerable value) { return value != null && value.Count() >= MinCount; } protected override string GenerateErrMsg(IEnumerable value) { return ErrMsg.Replace("{fieldValue}", (value?.Count() ?? 0).ToString()).Replace("{MinCount}", MinCount.ToString()); } } /// /// 检查列表最大数量 /// public sealed class CheckIEnumerableTMaxCountAttribute : BaseCheckIEnumerableTAttribute { /// /// 列表数量 /// public int MaxCount { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}.Length={fieldValue}不合法,应小于等于{MaxCount} /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}.Length={fieldValue}不合法,数量应大于{MinCount}"; _errMsg = "列表长度={fieldValue}不合法,应小于等于{MaxCount}"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(IEnumerable value) { return value == null || value.Count() <= MaxCount; } protected override string GenerateErrMsg(IEnumerable value) { return ErrMsg.Replace("{fieldValue}", (value?.Count() ?? 0).ToString()).Replace("{MaxCount}", MaxCount.ToString()); } } /// /// 检查字符串是否为指定可选值之一 /// public sealed class CheckStringInMapAttribute : BaseCheckStringAttribute { /// /// 可选值列表 /// public string[] Map { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,值应为{Map}之一 /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值应为{Map}"; _errMsg = "值应为{Map}"; if (Map.Length > 1) { _errMsg += "之一"; } } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { return Map.Contains(value ?? ""); } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{Map}", string.Join(",", Map)); } } /// /// 检查字符串长度是否为可选值之一 /// public sealed class CheckStringLengthInMapAttribute : BaseCheckStringAttribute { /// /// 可选值列表 /// public int[] Map { get; set; } private string _errMsg; /// /// 错误提示 /// 默认为:{fieldName}={fieldValue}不合法,长度应为{Map}之一 /// public override string ErrMsg { get { if (string.IsNullOrWhiteSpace(_errMsg)) { //_errMsg = "{fieldName}={fieldValue}不合法,值应为{Map}之一"; _errMsg = "内容长度={fieldValue}不合法,长度应为{Map}之一"; } return _errMsg; } set { _errMsg = value; } } protected override bool Execute(string value) { var length = value.Length; return Map.Contains(length); } protected override string GenerateErrMsg(string value) { return ErrMsg.Replace("{fieldValue}", value).Replace("{Map}", string.Join(",", Map)); } } #endregion #region Condition /// /// 检查条件基类 /// [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public abstract class BaseCheckConditionAttribute : Attribute { /// /// 条件字段名 /// 应填写当前对象可访问到的字段 /// public string ConditionName { get; set; } private string[] _checkHandleNameArr; /// /// 绑定满足条件后的处理逻辑 /// 不填时依次执行CheckName为空的操作 /// public string[] CheckHandleNameArr { get { if (_checkHandleNameArr == null) { return new string[] { null }; } return _checkHandleNameArr; } set { _checkHandleNameArr = value; } } public abstract bool Execute(object value); } /// /// 检查指定字段的值是否等于预设值 /// public sealed class CheckConditionStringValueAttribute : BaseCheckConditionAttribute { /// /// 预设值 /// public string ConditionValue { get; set; } public override bool Execute(object value) { return value?.ToString() == ConditionValue; } } /// /// 检查指定字段的值是否不等于预设值 /// public sealed class CheckConditionStringNEQValueAttribute : BaseCheckConditionAttribute { /// /// 预设值 /// public string ConditionValue { get; set; } public override bool Execute(object value) { return value?.ToString() != ConditionValue; } } /// /// 检查指定字段的值是否在范围内 /// public sealed class CheckConditionIntInRangeAttribute : BaseCheckConditionAttribute { /// /// 最小值 /// 默认为int.MinValue /// public int MinValue { get; set; } = int.MinValue; /// /// 最大值 /// 默认为int.MaxValue /// public int MaxValue { get; set; } = int.MaxValue; public override bool Execute(object value) { if (double.TryParse((value ?? "").ToString(), out var temp)) { return temp >= MinValue && temp <= MaxValue; } return false; } } /// /// 检查指定字段的值是否不在范围内 /// public sealed class CheckConditionIntNotInRangeValueAttribute : BaseCheckConditionAttribute { /// /// 最小值 /// 默认为int.MinValue /// public int MinValue { get; set; } = int.MinValue; /// /// 最大值 /// 默认为int.MaxValue /// public int MaxValue { get; set; } = int.MaxValue; public override bool Execute(object value) { if (double.TryParse((value ?? "").ToString(), out double temp)) { return temp < MinValue || temp > MaxValue; } return false; } } /// /// 检查指定字段的值是否为可选值之一 /// public sealed class CheckConditionStringInMapAttribute : BaseCheckConditionAttribute { public string[] ConditionMap { get; set; } public override bool Execute(object value) { return ConditionMap.Contains(value?.ToString() ?? ""); } } /// /// 检查指定字段的值是否不为可选值 /// public sealed class CheckConditionStringNotInMapAttribute : BaseCheckConditionAttribute { public string[] ConditionMap { get; set; } public override bool Execute(object value) { return !ConditionMap.Contains(value?.ToString() ?? ""); } } #endregion /// /// 检查帮助类 /// /// public class CheckHelper where T:notnull { private readonly PropertyInfo[]? _properties = null; /// /// 属性缓存 /// 应通过方法访问 /// private Dictionary>? _propertyInfoDict = null; /// /// 检查不通过时回调的委托 /// /// 字段名 /// 字段值 /// 错误信息 public delegate void CheckErrorCallback(string fieldName, object value, string errMsg); public CheckHelper() { _properties = typeof(T).GetProperties(); } private Dictionary getPropertyInfos(T obj) { _propertyInfoDict ??= new Dictionary>(); if (!_propertyInfoDict.ContainsKey(obj)) { _propertyInfoDict[obj] = _properties.ToDictionary(K => K.Name, V => V.GetValue(obj)); } return _propertyInfoDict[obj]; } private bool checkCondition(List conditionAttributes, Dictionary dict) { var state = true; foreach (var item in conditionAttributes) { if (!dict.ContainsKey(item.ConditionName)) { throw new Exception($"当前对象中不存在 {item.ConditionName} 字段"); } state = item.Execute(dict[item.ConditionName]); if (!state) { break; } } return state; } private bool checkCondition(PropertyInfo pInfo, T obj, Func callback) { var state = true; var conditionAttrs = pInfo.GetCustomAttributes(typeof(BaseCheckConditionAttribute), true).Cast(); var conditGroup = conditionAttrs.GroupBy(O => O.CheckHandleNameArr == null ? "" : string.Join(",", O.CheckHandleNameArr)).ToDictionary(K => K.Key, V => V.ToList()); if (conditGroup.Count > 0) { foreach (var condit in conditGroup) { var dict = getPropertyInfos(obj); state = checkCondition(condit.Value, dict); if (state) { if (!callback(condit.Value[0].CheckHandleNameArr)) { break; } } } } else { callback(new[] { "" }); } return state; } private bool checkValue(string checkName, BaseCheckAttribute[] checkAttributes, PropertyInfo pInfo, T obj, out string errMsg) { errMsg = ""; var state = true; var attrs = checkAttributes.Where(O => (O.CheckHandleName ?? "") == checkName); foreach (var item in attrs) { state = item.Execute(pInfo.GetValue(obj)); if (!state) { errMsg = item.ErrMsg.Replace("{fieldName}", pInfo.Name); continue; } if (item.UseChangeValue) { pInfo.SetValue(obj, item.ChangedValue); } } return state; } /// /// 执行字段检查 /// /// 要检查的对象 /// 检查不通过时的回调 /// public bool ExecuteCheck(T obj, CheckErrorCallback callback) { var checkState = false; if (obj == null) { return checkState; } foreach (var p in _properties) { var attr = p.GetCustomAttributes(typeof(BaseCheckAttribute), true).Cast().ToArray(); if (attr.Length == 0) { continue; } checkCondition(p, obj, (checkNames) => { var status = true; foreach (var item in checkNames) { if (!checkValue(item ?? "", attr, p, obj, out var errMsg)) { callback(p.Name, p.GetValue(obj), errMsg); status = false; break; } } return status; }); } return checkState; } } }