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 { /// /// 方法上的model校验配置 /// public static Dictionary ValidatorCollection { get; } = new Dictionary(); public static void Add(this ValidatorModel validatorGroup, Expression> 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()}的表达式已经注册过了"); } } /// /// 方法上的普通参数校验配置 /// public static Dictionary ValidatorGeneralCollection { get; } = new Dictionary(); /// /// 默认校验的是string类型 /// /// 普通参数名 /// 校验错误时显示的提示名字 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); } /// /// /// /// 普通参数名 /// 校验错误时显示的提示名字 /// 参数类型 /// 最大小度(最小值) /// 最大长度(最大值) 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()}参数配置已经注入过了"); } } /// /// 自定义验证 /// /// /// public static void Add(this ValidatorGeneral general, string CNName, Func customValidator) { GeneralOptions options = new GeneralOptions(general, CNName, customValidator); if (!ValidatorGeneralCollection.TryAdd(general.ToString().ToLower(), options)) { throw new Exception($"键{general.ToString()}参数配置已经注入过了"); } } /// /// 获取方法上绑定的model校验字段 /// /// /// public static string[] GetModelParameters(this ValidatorModel validatorGroup) { return validatorGroup.ToString().GetModelParameters(); } /// /// 获取方法上绑定的model校验字段 /// /// /// public static string[] GetModelParameters(this string validatorGroup) { if (!ValidatorCollection.TryGetValue(validatorGroup.ToLower(), out string[] values)) { Console.WriteLine($"未注册{validatorGroup}参数的表达式"); throw new Exception($"未注册{validatorGroup}参数的表达式"); } return values; } /// /// 获取方法上绑定校验字段的配置信息 /// /// /// public static IEnumerable GetGeneralOption(this ValidatorGeneral[] general) { return general.Select(x => x.ToString()).ToArray().GetGeneralOption(); } /// /// 获取方法上绑定校验字段的配置信息 /// /// /// public static IEnumerable 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(); if (!objectModel.Status) { context.Result = new JsonResult(objectModel); return; } //判断是否提交了model参数 if (!objectModel.HasModelContent) { context.Result = new JsonResult(new WebResponseContent().Error($"请提交参数")); return; } } /// /// 是否添加了ModelValidator实体校验 /// /// /// public static bool ExistsActionModelValidator(this ActionExecutingContext context) { return context.ActionDescriptor.EndpointMetadata.Any(item => item is ObjectModelValidatorFilter); } /// /// 是否添加了ModelValidator实体校验 /// /// /// public static string[] GetModelValidatorParams(this ActionContext actionContext) { return (actionContext.ActionDescriptor .EndpointMetadata .Where(item => item is ObjectModelValidatorFilter) .FirstOrDefault() as ObjectModelValidatorFilter)?.MethodsParameters; } /// /// model校验 /// /// /// /// /// 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(); } /// /// 普通参数校验 /// /// 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 }); } /// ///参数验证没有通过的直接返回校验结果 /// /// /// public static void ErrorResult(this ActionContext actionContext, string message) { ObjectModelValidatorState objectModel = actionContext.HttpContext.GetService(); if (!objectModel.Status) { return; } objectModel.Status = false; objectModel.Message = message; } public static void OkModelResult(this ActionContext actionContext) { ObjectModelValidatorState objectModel = actionContext.HttpContext.GetService(); objectModel.HasModelContent = true; } } }