You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DSWMS/开发版dev/Vue.NetCore/Vue.Net/VOL.Core/ObjectActionValidator/ExpressValidator/MethodsValidator.cs

367 lines
15 KiB
C#

2 years ago
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using VOL.Core.Extensions;
using VOL.Core.Filters;
using VOL.Core.Utilities;
namespace VOL.Core.ObjectActionValidator
{
public static class MethodsValidator
{
/// <summary>
/// 方法上的model校验配置
/// </summary>
public static Dictionary<string, string[]> ValidatorCollection { get; } = new Dictionary<string, string[]>();
public static void Add<T>(this ValidatorModel validatorGroup, Expression<Func<T, object>> loginExpress = null)
{
if (!ValidatorCollection.TryAdd(validatorGroup.ToString().ToLower(),
loginExpress == null
? typeof(T).GetGenericProperties().Select(x => x.Name).ToArray()
: loginExpress.GetExpressionToArray()))
{
throw new Exception($"键{validatorGroup.ToString()}的表达式已经注册过了");
}
}
/// <summary>
/// 方法上的普通参数校验配置
/// </summary>
public static Dictionary<string, GeneralOptions> ValidatorGeneralCollection { get; } = new Dictionary<string, GeneralOptions>();
/// <summary>
/// 默认校验的是string类型
/// </summary>
/// <param name="general">普通参数名</param>
/// <param name="CNName">校验错误时显示的提示名字</param>
public static void Add(this ValidatorGeneral general, string CNName)
{
general.Add(CNName, ParamType.String, null, null);
}
public static void Add(this ValidatorGeneral general, string CNName, int? max)
{
general.Add(CNName, ParamType.String, null, max);
}
public static void Add(this ValidatorGeneral general, string CNName, ParamType type)
{
general.Add(CNName, type, null, null);
}
public static void Add(this ValidatorGeneral general, string CNName, ParamType type, int? max)
{
general.Add(CNName, type, null, max);
}
public static void Add(this ValidatorGeneral general, string CNName, int? min, int? max)
{
general.Add(CNName, ParamType.String, min, max);
}
/// <summary>
///
/// </summary>
/// <param name="general">普通参数名</param>
/// <param name="CNName">校验错误时显示的提示名字</param>
/// <param name="type">参数类型</param>
/// <param name="min">最大小度(最小值)</param>
/// <param name="max">最大长度(最大值)</param>
public static void Add(this ValidatorGeneral general, string CNName, ParamType type, int? min = null, int? max = null)
{
GeneralOptions options = new GeneralOptions(general, CNName, type, min, max);
if (!ValidatorGeneralCollection.TryAdd(general.ToString().ToLower(), options))
{
throw new Exception($"键{general.ToString()}参数配置已经注入过了");
}
}
/// <summary>
/// 自定义验证
/// </summary>
/// <param name="general"></param>
/// <param name="customValidator"></param>
public static void Add(this ValidatorGeneral general, string CNName, Func<object, ObjectValidatorResult> customValidator)
{
GeneralOptions options = new GeneralOptions(general, CNName, customValidator);
if (!ValidatorGeneralCollection.TryAdd(general.ToString().ToLower(), options))
{
throw new Exception($"键{general.ToString()}参数配置已经注入过了");
}
}
/// <summary>
/// 获取方法上绑定的model校验字段
/// </summary>
/// <param name="validatorGroup"></param>
/// <returns></returns>
public static string[] GetModelParameters(this ValidatorModel validatorGroup)
{
return validatorGroup.ToString().GetModelParameters();
}
/// <summary>
/// 获取方法上绑定的model校验字段
/// </summary>
/// <param name="validatorGroup"></param>
/// <returns></returns>
public static string[] GetModelParameters(this string validatorGroup)
{
if (!ValidatorCollection.TryGetValue(validatorGroup.ToLower(), out string[] values))
{
Console.WriteLine($"未注册{validatorGroup}参数的表达式");
throw new Exception($"未注册{validatorGroup}参数的表达式");
}
return values;
}
/// <summary>
/// 获取方法上绑定校验字段的配置信息
/// </summary>
/// <param name="general"></param>
/// <returns></returns>
public static IEnumerable<GeneralOptions> GetGeneralOption(this ValidatorGeneral[] general)
{
return general.Select(x => x.ToString()).ToArray().GetGeneralOption();
}
/// <summary>
/// 获取方法上绑定校验字段的配置信息
/// </summary>
/// <param name="general"></param>
/// <returns></returns>
public static IEnumerable<GeneralOptions> GetGeneralOption(this string[] generalName)
{
foreach (string item in generalName)
{
if (!ValidatorGeneralCollection.TryGetValue(item.ToLower(), out GeneralOptions options))
{
throw new Exception($"未注册{generalName.ToString()}参数的配置");
}
yield return options;
}
}
public static void ActionParamsValidator(this ActionExecutingContext context)
{
//普通参数校验
context.GeneralValidator();
//是否使用了model参数校验
if (!context.ExistsActionModelValidator()) return;
//判断当前model校验是否通垸
ObjectModelValidatorState objectModel = context.HttpContext.GetService<ObjectModelValidatorState>();
if (!objectModel.Status)
{
context.Result = new JsonResult(objectModel);
return;
}
//判断是否提交了model参数
if (!objectModel.HasModelContent)
{
context.Result = new JsonResult(new WebResponseContent().Error($"请提交参数"));
return;
}
}
/// <summary>
/// 是否添加了ModelValidator实体校验
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static bool ExistsActionModelValidator(this ActionExecutingContext context)
{
return context.ActionDescriptor.EndpointMetadata.Any(item => item is ObjectModelValidatorFilter);
}
/// <summary>
/// 是否添加了ModelValidator实体校验
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
public static string[] GetModelValidatorParams(this ActionContext actionContext)
{
return (actionContext.ActionDescriptor
.EndpointMetadata
.Where(item => item is ObjectModelValidatorFilter)
.FirstOrDefault() as ObjectModelValidatorFilter)?.MethodsParameters;
}
/// <summary>
/// model校验
/// </summary>
/// <param name="actionContext"></param>
/// <param name="prefix"></param>
/// <param name="model"></param>
/// <returns></returns>
public static void ModelValidator(this ActionContext actionContext, string prefix, object model)
{
string[] parameters = actionContext.GetModelValidatorParams();
//没有设置模型校验的直接返回
if (parameters == null) return;
if (model == null)
{
actionContext.ErrorResult("没有获取到参数");
return;
}
//model==list未判断
PropertyInfo[] properties = model.GetType().GetProperties().Where(x => parameters.Contains(x.Name.ToLower())).ToArray();
foreach (var item in properties)
{
if (!item.ValidationRquiredValueForDbType(item.GetValue(model), out string message))
{
actionContext.ErrorResult(message);
return;
}
}
actionContext.OkModelResult();
}
/// <summary>
/// 普通参数校验
/// </summary>
/// <param name="actionContext"></param>
public static void GeneralValidator(this ActionExecutingContext actionContext)
{
if (actionContext.ActionDescriptor
.EndpointMetadata
.Where(item => item is ObjectGeneralValidatorFilter)
.FirstOrDefault() is ObjectGeneralValidatorFilter objectGeneral)
{
foreach (GeneralOptions general in objectGeneral.MethodsParameters)
{
if (actionContext.Result != null) return;
if (!actionContext.HttpContext.Request.Query.TryGetValue(general.Name, out StringValues value))
{
actionContext.ActionErrorResult($"请提交参数[{general.CNName}]");
return;
}
if (string.IsNullOrEmpty(value))
{
actionContext.ActionErrorResult($"参数[{general.CNName}]不能为空");
return;
}
//自定义验证
if (general.CustomValidator != null)
{
ObjectValidatorResult validatorResult = general.CustomValidator(value);
if (!validatorResult.Status)
{
actionContext.ActionErrorResult(validatorResult.Message);
return;
}
continue;
}
actionContext.ValidatorValue(general, value);
}
}
}
public static void ValidatorNumber(Type type, object value)
{
value.ChangeType(type);
}
public static void ValidatorValue(this ActionExecutingContext actionContext, GeneralOptions options, object model)
{
if (model == null)
{
actionContext.ActionErrorResult($"请提交参数{options.CNName}");
return;
}
if (options.Min == null && options.Max == null) return;
switch (options.ParamType)
{
//待完ParamType.Long,Byte类型
case ParamType.Int:
//case ParamType.Long:
//case ParamType.Byte:
if (!int.TryParse(model.ToString(), out int _number))
{
actionContext.ActionErrorResult($"[{options.CNName}]必须是整数");
break;
}
if (options.Min != null && _number < options.Min)
{
actionContext.ActionErrorResult($"[{options.CNName}]不能小于[{options.Min}]");
break;
}
if (options.Max != null && _number > options.Max)
{
actionContext.ActionErrorResult($"[{options.CNName}]不能大于[{options.Max}]");
}
break;
case ParamType.String:
string value = model.ToString();
if (options.Min != null && value.Length < options.Min)
{
actionContext.ActionErrorResult($"[{options.CNName}]至少[{options.Min}]个字符");
}
if (options.Max != null && value.Length > options.Max)
{
actionContext.ActionErrorResult($"[{options.CNName}]最多[{options.Max}]个字符");
}
break;
//待完日期大小
case ParamType.DateTime:
if (!DateTime.TryParse(model.ToString(),out _))
{
actionContext.ActionErrorResult($"[{options.CNName}]应该是日期格式");
}
break;
//min,max应该是decimal类型待完
case ParamType.Decimal:
if (!decimal.TryParse(model.ToString(), out decimal _decimal))
{
actionContext.ActionErrorResult($"[{options.CNName}]不是数字");
break;
}
if (options.Min != null && _decimal < options.Min)
{
actionContext.ActionErrorResult($"[{options.CNName}]不能小于[{options.Min}]");
break;
}
if (options.Max != null && _decimal > options.Max)
{
actionContext.ActionErrorResult($"[{options.CNName}]不能大于[{options.Max}]");
}
break;
case ParamType.Guid:
if (!Guid.TryParse(model.ToString(), out _))
{
actionContext.ActionErrorResult($"[{options.CNName}]不是Guid类型");
}
break;
default:
break;
}
}
public static void ActionErrorResult(this ActionExecutingContext actionContext, string message)
{
actionContext.Result = new JsonResult(new { Status = false, Message = message });
}
/// <summary>
///参数验证没有通过的直接返回校验结果
/// </summary>
/// <param name="actionContext"></param>
/// <param name="message"></param>
public static void ErrorResult(this ActionContext actionContext, string message)
{
ObjectModelValidatorState objectModel = actionContext.HttpContext.GetService<ObjectModelValidatorState>();
if (!objectModel.Status)
{
return;
}
objectModel.Status = false;
objectModel.Message = message;
}
public static void OkModelResult(this ActionContext actionContext)
{
ObjectModelValidatorState objectModel = actionContext.HttpContext.GetService<ObjectModelValidatorState>();
objectModel.HasModelContent = true;
}
}
}