前言
上一章我们在控制台中基本的了解了FluentValidation是如何简洁,优雅的完成了对实体的验证工作,今天我们将在实战项目中去应用它。
首先我们创建一个ASP .会员管理系统项目,本人环境是VS2017,
创建成功后通过在框架中使用安装-软件包验证-版本7.6.104安装FluentValidation
在模型文件夹中添加两个实体地址和人
公共类地址{公共字符串主页{ get设置;}公共字符串电话{ get设置;} }公开课Person { ///summary ///姓名////摘要公共字符串名称{ get设置;} ///摘要///年龄////summary public int Age { get;设置;} ///摘要///性别////汇总公共bool Sex { get设置;} ///摘要///地址////摘要公共地址{获取设置;} }紧接着创建实体的验证器
公共类地址验证器:抽象验证地址{ public AddressValidator() { this .规则为(m=m.Home).NotEmpty().WithMessage('家庭住址不能为空');这个。电话规则NotEmpty().WithMessage('手机号码不能为空');} }公共类PersonValidator : abstractvalidator person { public PersonValidator(){ this .规则为(p=p。名称)。NotEmpty().WithMessage('姓名不能为空');这个。年龄规则NotEmpty().WithMessage('年龄不能为空');这个。规则为(p=p。地址)。SetValidator(新的地址验证器());} }为了更好的管理验证器,我建议将使用一个经理者来管理所有验证器的实例。如ValidatorHub
公共类ValidatorHub {公共地址验证器地址验证器{ get设置;}=新地址验证器();public PersonValidator PersonValidator { get;设置;}=new PersonValidator();}现在我们需要创建一个页面,在默认的家庭控制器控制器下添加2个操作:验证测试,他们一个用于展示页面,另一个则用于提交。
[HttpGet]公共操作结果ValidatorTest(){ return View();}[httpset]公共动作结果验证器测试(Person模型){ return View();}为ValidatorTest添加视图,选择创造模板,实体为人
将默认的@Html全部删掉,因为在我们本次介绍中不需要,我们的目标是搭建一个前后端分离的项目,而不要过多的依赖于MVC。
最终我们将表单改写成了
@使用(Html .begin inform()){ @ Html .antiforgrytoken()div class=' form-horizontal ' H4 PeRsoN/H4 HR/@ Html .ValidationSummary(true ' ',new { @ class=' text-danger ' })div class=' form-group '标签为=' Name ' class=' control-label col-MD-2 '姓名/label div class='col-md-10 '输入类型=' text ' Name=' Name ' class=' form-control '/div/div class=' form-group '标签为=' Age ' class=' control-label col-MD-2 '年龄/label div class='col-md-10 '输入类型=“文本”名称=' Age ' class=' form-control '/div/div class=' form-group '标签为=' Home ' class=' control-label col-MD-2 '住址/label div class='col-md-10 '输入类型=“文本”名称='地址.home ' class=' form-control '/div/div class=' form-group '标签为=' Phone ' class=' control-label col-MD-2 '电话/label div class='col-md-10 '输入类型=“文本”名称='地址.phone ' class=' form-control '/div/div class=' form-group '标签为=' Sex ' class=' control-label col-MD-2 '性别/label div class=' col-MD-10 ' div class=' checkbox '输入类型='复选框'名称=' Sex '/div/div/div class=' form-group ' div class=' col-MD-offset-2 col-MD-10 '输入类型='提交'值=' Create ' class=' BTN BTN-默认'/div/div/div }注意,由于我们的实体人中存在复杂类型地址,我们都知道,表单提交默认是键:值形式,而在传统表单的key:value中,我们无法实现让键为地址的情况下价值为一个复杂对象,因为投入一次只能承载一个值,且必须是字符串。实际上手动音量调节中存在模型绑定,此处不作过多介绍(因为我也忘记了-_-||)。
简单来说,就是可以帮助我们根据你需要的类型,尽可能的自动转换。目前,只要我们知道如何正确使用它,地址中就有Home属性和Phone属性。我们可以将表单的名称设置为Address.Home. MVC模型绑定将解析Address。对象地址的Home属性的home。
我没有介绍太多简单的验证方法。在前一章中,我们已经了解到可以通过创建实体验证器来验证实体,然后通过IsValid属性来判断验证是否成功。是的,没错。对每个人来说都太简单了。但是我们每次检查的时候创建一个验证器是不是有点麻烦?别忘了我们刚刚创建了一个ValidatorHub。我们知道默认情况下控制器继承自控制器。如果我们想扩展控制器的某些功能,该怎么办?现在我将创建一个控制器,并从控制器继承它。
公共类Controller ex : Controller { protected dictionary string,string DicError { get设置;}=new Dictionarystring,string();受保护的ValidatorHub ValidatorHub { get设置;}=new ValidatorHub();受保护的覆盖void onationexecuted(ActionExecutedContext filter context){ base。OnActionExecuted(筛选器上下文);视图数据['错误']=DicError;}受保护的void ValidatorErrorHandler(ValidationResult result){ foreach(var)在结果中失败。错误){ if(!这个。包含密钥(失败。property name(){ this。添加(失败。属性名,失败。error message);}}}}我在ControllerEx中创建了一个ValidatorHub属性。顾名思义,其中有各种验证器实体。有了它,我们就可以在待验证的Action中通过这个. ValidatorHub .混凝土验证器完成具体的验证工作,而不必每次都去新的一个验证器。
同样,我定义了一组DicError的键值对,它们的键和值类型都是字符串。Key是验证失败的属性的名称,value是验证失败后的错误消息,用来存在验证的结果。
在这里,我还定义了一个ValidatorErrorHandler的方法。其参数之一是验证结果。我们已经通过名字大致猜到了这个函数。我们处理验证错误,遍历验证结果的错误信息,并将错误信息添加到DicError集合中。
最后,我需要将这个错误传递给视图。简单的方法就是ViewData['Error'],但是我不想在每一页都这样做,因为这样会让我写很多遍这段代码,我会厌倦的。很棒的是,MVC框架为我们提供了Filter(有些地方也叫函数钩子、节编程、过滤器),方便我们在生命周期的不同阶段进行控制。显然,我的要求是在每个Action之后的末尾添加一句ViewData['Error']=DicError。所以我重写了OnActionExecuted方法,只添加了view data[' Error ']=DicError;
现在我只需要从ControllerEx继承HomeController就可以享受以上所有功能。
现在,基础工作基本完成,但我们还是忽略了一个问题。我的错误是视图数据中有一个错误['错误'],但是我们在验证错误时是否在页面上显示错误列表?比如李?这显然不是我们想要的。我们还需要一个功能来帮助我们合理地显示错误信息。在Razor中,我们可以扩展HtmlHelper。所以我为HtmlHelper扩展了一个ValidatorMessageFor方法
公共静态类ValidatorHelper { public static MvcHtmlString ValidatorMessageFor(此HtmlHelper为htmlHelper,String属性,对象错误){ var dicError=error as dictionary string,string;If (dicError==null) //无错误{//不等于null}否则{If (Dicerror。Containskey(属性){返回新的MVC HTMLString(字符串。格式(' p {0}/p ',Dicerror[属性]);} }返回新的mvchtmlString(“”);}}需要ValidatorMessaegFor中的两个参数属性和错误
前者是要显示的错误属性名,后者是错误对象,即ViewData['Error']。功能很简单。当在错误对象中发现关键字是错误属性名称时,用P标记包装该值并返回,该值是错误属性对应的错误提示消息。
目前,我们需要在视图的每个输入下添加一个句子,如:@ html.validatemessagefor ('name ',Viewdata ['error'])。
@使用(Html。begin inform()){ @ Html。antiforgrytoken()div class=' form-horizontal ' H4PeRsoN/H4 HR/@ Html。ValidationSummary(true,'',New { @ class=' text-dancer ' })div class=' form-group '标签为=' Name ' class=' control-label col-MD-2 ' Name/label div class=' col-MD-10 '输入类型=' text ' Name=' Name ' class=' form-control '/@ Html。ValidatorMessageFor('Name ',view data[' error '])/div/div class=' form-group '标签for=' Age ' class=' control-label col-MD-2 ' Age/label div class=' col-MD-10 '输入类型=' text ' Name=' Age ' class=' form-control '/@ Html。ValidatorMessageFor('Name ',view data[' error '])/div/div class=' form-group '标签为=' home ' class=' control-label col-MD-2 '地址/label div class='col-md-10 '输入类型='text' name='Address。home ' class=' form-control '/@ Html。验证消息(地址。Home ',View data[' error '])/div/div class=' form-group '标签为=' phone ' class=' control-label col-MD-2 ' phone/label div class=' col-MD-10 '输入类型='text' name='Address。phone ' class=' form-control '/@ Html。验证消息(地址。Phone ',View data[' error '])/Div/Div class=' form-group '标签为=' Sex ' class=' control-label col-MD-2 ' gender/label Div class=' col-MD-10 ' Div class='checkbox '输入类型=' checkbox '名称=' Sex '/Div/Div/Div class=' form-group ' Div class=' col-MD-offset-2col-MD-10 '输入类型=' submit '值=' create ' class=' btnbtn-default '/Div/Div
[httpset]public action result validator test(Person模型){ var result=this。ValidatorHub . personvalidator . validate(模型);if(结果。IsValid){ return Redirect(' https://www . Baidu.com ');} else { this。ValidatorErrorHandler(结果);}返回视图();}通过我们在ControllerEx中的ValidatorHub验证实体Person。如果验证成功.如果这里没什么可做的,就跳下去。否则,调用Ex中的ValidatorErrorHandler将错误消息绑定到ViewData['Error'],这样在呈现前端视图时就可以显示错误消息。
接下来,我们将运行程序。
如你所见,当我点击提交时,虽然只输入了电话号码,但其他三个表单都被清空了,也许我们会感到不舒服。当然,如果你需要的话,我相信你看完上面的错误消息绑定就可以解决这个问题,但其实我们并不需要。 (o)/~
为什么呢?因为我们还是需要前端验证的,当前端验证失败的时候,是不能发送到后端的,所以不用担心验证失败的时候,用户已经填写的一些表单数据会被清空。
这里提到提交表单时需要前端验证。既然有前端验证,为什么还要做后端验证?你没脱裤子放屁吗?其实前端验证的功能是优化用户体验,减轻服务器压力,防君子,但绝不防小人。由于Web客户端的不确定性,一切都可以模拟。如果不做服务器端验证,如果你的系统涉及到资金,你可能会在那天醒来发现自己破产了。
来一个认证的。
摘要
以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。