在 日常的后端api开发过程中呢,可能我待的公司不多,其实微软已经在框架中已经封装好了 模型验证,公司项目在实际使用中,感觉就知道的人感觉很少,这……
这么好用的参数验证器,为啥都不使用呢,呵呵!
模型验证高级用法请参照官网,下面介绍下自定义的简单用法
比如:
public class Persion
{
public int Id{get;set;}
public string Name{get;set;}
}
public TResopnse GetkkByIdd(Persion input)
{
//很多人习惯会这样写
if(input.Id <= 0)
{
return new TResopnse("参数Id错误");
}
if(string.isNullOrStringEmpry(input.Name))
{
return new TResopnse("参数Name错误");
}
}
很显然,这样写,如果参数非常多,那这个 方法的验证代码不会显得很臃肿吗??
于是,我见到升级版本的写法
public class Persion
{
public int Id{get;set;}
public string Name{get;set;}
public (int code,string msg) Verification()
{
if(input.Id <= 0)
{
return (-1,"参数Id错误");
}
if(string.IsNullOrEmpty(input.Name))
{
return (-1,"参数Name错误");
}
}
}
public TResopnse GetkkByIdd(Persion input)
{
(int code,string msg) = input.Verification();
if(code== -1 )
{
return new TResopnse(msg);
}
}
对此,感觉好像高级了些 (¬、¬) (¬_¬) 呵呵呵
设置参数校验方式(netcore 和 netFramework通用)
netcore 和 netFramework 都有验证属性,引用命名空间:using System.ComponentModel.DataAnnotations;
例:[StringLength] 等其他自行百度 ,如果 特性验证不能满足你的需求,你还可以 自定义验证方式 继承 IValidatableObject ,实现他的方法
// 简易版
public class Persion
{
[Range(6, 21, ErrorMessage = "密码长度不够")]
public int Id{get;set;}
//[Required(ErrorMessage = "姓名不能为空")]
// StringLength
public string Name{get;set;}
}
//自定义版本
public class Persion :IValidatableObject
{
public int Id{get;set;}
public string Name{get;set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(input.Id <= 0)
{
yield return new ValidationResult("姓名不能为空", new[] { nameof(Name) })
}
if (Name.IsNullOrEmpty())
{
yield return new ValidationResult("姓名不能为空", new[] { nameof(Name) })
}
}
}
拦截验证参数
netcore 在中间件统一拦截验证,也可以通过Filter验证
对本次请求的参数验证不通过统一返回出去,不再进入 action ,对 action 代码 无代码入侵,这样不就挺好的吗,即实现了参数校验,又能保证 action 代码的整洁,完成了 参数校验代码的解耦,也是不是能体现除单一职责的模式呢!哈哈
public class ControllerActionFilter : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!context.ModelState.IsValid)
{
foreach (var item in context.ModelState.Values)
{
if (item.Errors.Count > 0)
{
var result = ReturnMsg.Success(-1, item.Errors[0].ErrorMessage);
context.Result = new JsonResult(result);
return;
}
}
}
var callBackResult = await next(); //继续管道
}
}
netFramework 在Filter统一拦截验证
using System.Web.Http.Filters;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class RecordLogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ActionArguments.Count > 0)
{
if (!actionContext.ModelState.IsValid)
{
string parmsMsg = null;
var error = actionContext.ModelState.Values.Where(p => p.Errors.Count > 0);
foreach (var item in error)
{
parmsMsg = item.Errors.FirstOrDefault().ErrorMessage;
break;
}
if (!string.IsNullOrWhiteSpace(parmsMsg))
{
CommonResponse<bool> result = CommonResponse<bool>.GetResult(0, parmsMsg, false);
actionContext.Response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(result), null, "application/json")
};
return;
}
}
}
}
}