using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_Core.Attributes;
|
using WIDESEA_Core.Helper;
|
|
namespace WIDESEA_Core.Utilities
|
{
|
public class ModelValidate
|
{
|
/// <summary>
|
/// 验证模型数据是否符合定义的验证规则
|
/// </summary>
|
/// <typeparam name="T">要验证的模型类型</typeparam>
|
/// <param name="data">要验证的模型数据</param>
|
/// <returns>包含验证结果、错误信息和原始数据的元组</returns>
|
/// <remarks>
|
/// 返回值说明:
|
/// Item1 - 验证是否通过 (true/false)
|
/// Item2 - 验证失败时的错误信息
|
/// Item3 - 原始传入的数据对象
|
/// </remarks>
|
public static (bool, string, object?) ValidateModelData<T>(T data) where T : class, new()
|
{
|
Type modelType = typeof(T);
|
if (data == null) return (false, "传入参数不可为null", data);
|
ModelValidateAttribute? modelAttribute = modelType.GetCustomAttribute<ModelValidateAttribute>();
|
if (modelAttribute == null) return (false, $"{modelType.Name}未定义【ModelValidateAttribute】特性", data);
|
PropertyInfo[] propertyInfos = modelType.GetProperties();
|
return SimpleValidate(propertyInfos, data);
|
}
|
|
/// <summary>
|
/// 验证模型数据集合的有效性
|
/// </summary>
|
/// <typeparam name="T">模型类型</typeparam>
|
/// <param name="datas">待验证的模型数据集合</param>
|
/// <returns>
|
/// 元组包含三个值:
|
/// Item1 - 验证结果(true/false)
|
/// Item2 - 验证失败时的错误信息
|
/// Item3 - 验证失败时的错误数据对象
|
/// </returns>
|
/// <remarks>
|
/// 该方法会检查集合是否为null/空,并验证每个数据项的ModelValidateAttribute特性和属性值
|
/// </remarks>
|
public static (bool, string, object?) ValidateModelData<T>(List<T> datas) where T : class, new()
|
{
|
Type modelType = typeof(T);
|
if (datas == null) return (false, "传入参数不可为null", datas);
|
if (datas.Count == 0) return (false, "集合个数不可等于0", datas);
|
foreach (T data in datas)
|
{
|
if (data == null) return (false, "传入参数不可为null", data);
|
ModelValidateAttribute? modelAttribute = modelType.GetCustomAttribute<ModelValidateAttribute>();
|
if (modelAttribute == null) return (false, $"{modelType.Name}未定义【ModelValidateAttribute】特性", data);
|
PropertyInfo[] propertyInfos = modelType.GetProperties();
|
(bool, string, object?) result = SimpleValidate(propertyInfos, data);
|
if (!result.Item1) return result;
|
}
|
|
return (true, $"成功", datas);
|
}
|
|
//private static (bool, string, object?) CustomMethodValidate<T>(ModelValidateAttribute modelAttribute, T data) where T : class, new()
|
//{
|
// try
|
// {
|
// if (modelAttribute.CustomValidateMethodTypeName == null) return (false, $"自定义验证方法需要提供方法所在类的类型对象", data);
|
// if (modelAttribute.CustomValidateMethodName == null) return (false, $"自定义验证方法需要提供方法名", data);
|
|
// string path = Path.Combine(AppContext.BaseDirectory, $"{modelAttribute.CustomValidateAssemblyName}.dll");
|
// Assembly assembly = Assembly.LoadFrom(path);
|
|
// Type t = assembly.GetType(modelAttribute.CustomValidateAssemblyName + "." + modelAttribute.CustomValidateMethodTypeName);
|
// object bbb = App.GetService(t);
|
// MethodInfo? methodInfo = t.GetMethod(modelAttribute.CustomValidateMethodName);
|
// var result = methodInfo.Invoke(bbb, new object[] { data });
|
// //MethodInfo? methodInfo = modelAttribute.CustomValidateMethodType.GetMethod(modelAttribute.CustomValidateMethodName);
|
// //if (methodInfo == null) return (false, $"未在该类型对象【{modelAttribute.CustomValidateMethodType.Name}】中找到该方法【{modelAttribute.CustomValidateMethodName}】", data);
|
// //methodInfo.GetGenericArguments()
|
// return (true, "成功", data);
|
// }
|
// catch(Exception ex)
|
// {
|
// throw new Exception();
|
// }
|
|
//}
|
|
/// <summary>
|
/// 执行简单的模型属性验证
|
/// </summary>
|
/// <typeparam name="T">要验证的模型类型</typeparam>
|
/// <param name="propertyInfos">模型的属性信息集合</param>
|
/// <param name="data">要验证的模型实例</param>
|
/// <returns>验证结果元组:(是否验证通过, 验证消息, 原始数据)</returns>
|
/// <remarks>
|
/// 该方法会根据属性上的PropertyValidateAttribute特性进行以下验证:
|
/// 1. 非空验证(NotNullAndEmpty)
|
/// 2. 最小值验证(MinValue)
|
/// 3. 最大值验证(MaxValue)
|
/// 4. 关联属性非空验证(NotNullAndEmptyWithProperty)
|
/// 5. 关联属性特定值验证(NotNullAndEmptyWithPropertyAndValue)
|
/// </remarks>
|
private static (bool, string, object?) SimpleValidate<T>(PropertyInfo[] propertyInfos, T data) where T : class, new()
|
{
|
try
|
{
|
foreach (PropertyInfo propertyInfo in propertyInfos)
|
{
|
PropertyValidateAttribute? propertyAttribute = propertyInfo.GetCustomAttribute<PropertyValidateAttribute>();
|
if (propertyAttribute == null) continue;
|
|
object? value = propertyInfo.GetValue(data, null);
|
if (propertyAttribute.NotNullAndEmpty)
|
{
|
if (value == null) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}不可为null", data);
|
if (string.IsNullOrEmpty(value.ToString())) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}不可为空字符串", data);
|
}
|
|
if (propertyAttribute.MinValue > int.MinValue)
|
{
|
if (value == null) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}不可为null", data);
|
if (propertyAttribute.IsContainMinValue)
|
{
|
if (Convert.ToInt32(value.ToString()) < propertyAttribute.MinValue) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}的值【{value}】不可小于【{propertyAttribute.MinValue}】", data);
|
}
|
else
|
{
|
if (Convert.ToInt32(value.ToString()) <= propertyAttribute.MinValue) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}的值【{value}】要大于【{propertyAttribute.MinValue}】", data);
|
}
|
}
|
|
if (propertyAttribute.MaxValue < int.MaxValue)
|
{
|
if (value == null) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}不可为null", data);
|
if (propertyAttribute.IsContainMaxValue)
|
{
|
if (Convert.ToInt32(value.ToString()) >= propertyAttribute.MaxValue) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}的值【{value}】不可大于【{propertyAttribute.MaxValue}】", data);
|
}
|
else
|
{
|
if (Convert.ToInt32(value.ToString()) > propertyAttribute.MaxValue) return (false, $"{(string.IsNullOrEmpty(propertyAttribute.Description) ? propertyInfo.Name : propertyAttribute.Description)}的值【{value}】要小于【{propertyAttribute.MaxValue}】", data);
|
}
|
}
|
|
if (!string.IsNullOrEmpty(propertyAttribute.NotNullAndEmptyWithProperty))
|
{
|
PropertyInfo? property = propertyInfos.FirstOrDefault(x => x.Name == propertyAttribute.NotNullAndEmptyWithProperty);
|
if (property != null)
|
{
|
object? tempValue = property.GetValue(data);
|
if (tempValue != null && !string.IsNullOrEmpty(tempValue.ToString()))
|
{
|
Type[] types = propertyInfo.PropertyType.GenericTypeArguments;
|
if (types.Length == 1)
|
{
|
string str = value.Serialize();
|
if (str == "[]")
|
{
|
return (false, $"【{property.Name}】属性的值非空时【{propertyInfo.Name}】属性的值也不可为空", data);
|
}
|
}
|
else if (types.Length == 0)
|
{
|
if (value == null)
|
{
|
return (false, $"【{property.Name}】属性的值非空时【{propertyInfo.Name}】属性的值也不可为空", data);
|
}
|
}
|
|
}
|
}
|
else
|
{
|
return (false, $"未找到【{propertyInfo.Name}】特性属性【{propertyAttribute.NotNullAndEmptyWithProperty}】", data);
|
}
|
}
|
|
if (propertyAttribute.NotNullAndEmptyWithPropertyAndValue != null && propertyAttribute.NotNullAndEmptyWithPropertyAndValue.Length == 2)
|
{
|
PropertyInfo? property = propertyInfos.FirstOrDefault(x => x.Name == propertyAttribute.NotNullAndEmptyWithPropertyAndValue[0]);
|
if (property != null)
|
{
|
object? tempValue = property.GetValue(data);
|
if (tempValue != null && !string.IsNullOrEmpty(tempValue.ToString()))
|
{
|
Type[] types = propertyInfo.PropertyType.GenericTypeArguments;
|
if (types.Length == 1)
|
{
|
if (tempValue.ChangeType(property.PropertyType).ToString() == propertyAttribute.NotNullAndEmptyWithPropertyAndValue[1].ChangeType(property.PropertyType).ToString())
|
{
|
string str = value.Serialize();
|
if (str == "[]")
|
{
|
return (false, $"【{property.Name}】属性的值为【{propertyAttribute.NotNullAndEmptyWithPropertyAndValue[1]}】时【{propertyInfo.Name}】属性的值不可为空", data);
|
}
|
}
|
|
}
|
else if (types.Length == 0)
|
{
|
if (tempValue.ChangeType(property.PropertyType).ToString() == propertyAttribute.NotNullAndEmptyWithPropertyAndValue[1].ChangeType(property.PropertyType).ToString() && value == null && string.IsNullOrEmpty(value.ToString()))
|
{
|
return (false, $"【{property.Name}】属性的值为【{propertyAttribute.NotNullAndEmptyWithPropertyAndValue[1]}】时【{propertyInfo.Name}】属性的值不可为空", data);
|
}
|
}
|
|
}
|
}
|
else
|
{
|
return (false, $"未找到属性【{propertyAttribute.NotNullAndEmptyWithProperty}】", data);
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
return (false, $"数据验证异常,异常信息:{ex.Message}", data);
|
}
|
return (true, "验证成功", data);
|
}
|
}
|
}
|