概述

表单验证的最终效果大家都懂,这里不阐述了,主要从宏观角度说说blazor中表单验证框架涉及到的类,以及它们是如何协作的,看完这个,再看官方文档也许能更轻松点。

blazor中的验证框架分为两部分:基础验证框架 和 基于数据注释Atrrbute的验证器,当然也提供了很多扩展点。注意我们通常使用数据注释Atrrbute的验证器,但它仅仅是在基础验证框架上扩展而来的,并不是核心,我们下面先分析基础验证框架,后续再说基于数据注释的验证。

表单验证是围绕表单,往往一个表单绑定到一个对象,我这里称为编辑模型,表单中的输入框与这个对象属性绑定。

我们先把基础验证框架看作一个整体,从几个角度分析:

  1. 产生验证消息,这个不属于验证框架的核心部分,验证框架只需要提供一个方法,当框架外部产生验证时,调用此方法,让验证框架去记录即可
  2. 存储验证消息是验证框架的核心工作之一,我们可以想象使用一个Dictionary<字段,List<验证消息>>来存储,key对应编辑模型的一个字段,value是验证消息集合,一个字段可能有多个验证消息。
  3. 我们可以定义两个组件用于展示验证消息,一个用于汇总展示,一个用户展示指定指定的验证消息,它们从验证框架获取验证信息进行显示。
  4. 清空验证消息,验证框架内部从存储中清空即可,可以向外暴露个事件,还可以留个方法允许外部主动调用清空验证消息,最好再允许外部清空指定字段的验证消息。
  5. 下面说明下blazor中表单验证的关键类,以及它们之间的关系。

基础验证框架先是定义几个零散的类,各自负责处理自己的部分,然后通过引用、方法调用把几个类串联起来。

字段标识FieldIdentifier

前面说存储验证消息时,类似这么个类型:Dictionary<字段,List<验证消息>>,简单的情况“字段”可以用个string类型,但我们是在内存中,可以用更直接的方式。

FieldIdentifier = 编辑模型的引用 + 字段名,它就代表编辑模型的某个字段。后续我们要操作某个字段,往往都是用这个参数。

验证消息存储器ValidationMessageStore

ValidationMessageStore是用这样一个字段Dictionary<FieldIdentifier, List<string>> _messages来存储验证消息的。key是字段,value是此字段的多个验证消息。也提供了插入、删除等验证消息等方法。

它一般是有我们自己的代码new出来的,或者有扩展的验证器,如 基于数据注释的验证器new出来的。new它的时候会把editContext对象传进来,后面会用。

当调用这个对象添加验证消息时,它会存储此字段的验证消息,并且调用editContext获取字段状态FieldState,将自身的引用传递给它,以便FieldState将来反向通过存储器来查询验证状态。

字段状态FieldState

FieldState表示字段的状态,所谓的状态就是 这个字段是否修改过、以及获取它关联的验证消息(本质上是从ValidationMessageStore获取,后面会说)。

为啥不跟字段标识FieldIdentifier合并为一个类呢?
字段标识只是代表某个字段,在很多方法参数时都会用到,它比较轻量;而字段状态是存储了字段是否修改和验证消息列表的,相对来说比较重,那些方法可能仅仅是想通过字段标识做查找,并不关心内部的状态

它包含一个ValidationMessageStore的列表,获取此字段的验证消息时,就是遍历这个列表获取的。但FieldState不负责向存储器添加验证消息。这个列表如何来的,验证消息存储器ValidationMessageStore已经说明了。

表单编辑上下文EditContext

可以把EditContext理解为 :字段状态FieldState列表 + 编辑模型实例,注意它不引用ValidationMessageStore,之所以这样设计是想保持EditContext轻量。

那主要关心的就是FieldState列表的crud操作
创建FieldState,则是外部想通过EditContext获取字段状态时,若有就返回,否则创建并记录下来。
读取就直接遍历FieldState咯。
删除:好像木有,也没有必要
改:找到字段状态,直接改咯。

另外:一个EditForm与一个EditContext关联,EditForm内部的组件会通过级联方式获得editContext的引用

额外的,它还提供字段变化时、请求验证时的相关事件。

小结

  1. 保持EditContext轻量,它不引用具体的验证存储器,而是只包含 字段状态 + 编辑模型实例,通过EditContext遍历里面的字段状态FieldState,获取验证消息,字段状态内部是遍历存储器列表获取验证消息。
  2. 将验证状态存储器抽离出来,哪里想向编辑上下文添加字段验证,就new ValidationMessageStore(editContext);然后Add验证消息即可。
  3. 便于扩展,比如后面的基于数据注解的验证器,它就是自己new ValidationMessageStore(editContext),然后使用注解验证方式向其添加验证。

验证消息的展示

展示就比较简单了,EditForm与EditContext关联的,它会级联传递到表单的子组件,子组件通过EditContext遍历字段就能拿到验证消息。

ValidationSummary

它是汇总显示所有验证消息,它通过级联参数获取EditContext引用,遍历然后显示验证消息。

ValidationMessage

原理类似,它显示指定字段的验证消息。

基于数据注释验证器扩展

所谓的验证器,无非是定义一个类,让它持有EditContext的引用,然后它内部new ValidationMessageStore(editContext),然后通过自己的方式验证后,Add验证消息到ValidationMessageStore即可。

DataAnnotationsValidator

组件是个空壳,它通过级联参数拿到EditContext对象,然后调用EditContextDataAnnotationsExtensions中定义的扩展方法,创建了一个实现IDispose的对象,组件释放时会释放这个对象

这个核心对象内部new ValidationMessageStore(editContext),用来存储验证消息。

它在初始化时会注册:

_editContext.OnFieldChanged += OnFieldChanged;
_editContext.OnValidationRequested += OnValidationRequested;

字段变化时,验证,或者外部向editContext请求验证时,触发验证。然后将验证消息Add到存储器中。

宏观上理解blazor中的表单验证的更多相关文章

  1. AngularJS中的表单验证

    AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 1.使用angularjs的表单验证 正则式验证 只需要配置一个正则 ...

  2. angular中的表单验证

    angular中的表单验证很强大, 一共有5中验证信息,$valid,$invalid,$pristine,$dirty,$error. $valid-----当验证通过的时候,为true,不通过的时 ...

  3. angular学习的一些小笔记(中)之表单验证

    表单验证 我去,我感觉我这个人其实还是一个很傻逼的一个人,老是因为拼错了一个单词或者怎么样就浪费我很长时间,这样真的不行不行,要正确对待这个问题,好了,说正题吧,angular也有表单验证minlen ...

  4. 关于Django中的表单验证

    ModelForm 和 普通的Form 都可以做表单验证 对于ModelForm如果只是想验证其中一部分model中的field,可以指定:内部类Meta的fields元素: fields = ('x ...

  5. JQuery中的表单验证及相关的内容

      前  言 JRedu Android应用开发中,经常要用到表单.既然用到了表单,那就不可避免的要用到表单的验证.但是,在提交表单时,但是,并不是,每次提交的表单内容都是正确的,如果 每次都将表单的 ...

  6. angularJS中的表单验证(包括自定义验证)

    表单验证是angularJS一项重要的功能,能保证我们的web应用不会被恶意或错误的输入破坏.Angular表单验证提供了很多表单验证指令,并且能将html5表单验证功能同他自己的验证指令结合起来使用 ...

  7. jq中的表单验证插件------jquery.validate

    今天我们来说一下表单验证,有人说我们在进行表单验证的时候使用正则来验证是非常麻烦的,现在我来给大家介绍一下表单验证的插件:jquery.validate.min.js 它是与jquery一起结合用来使 ...

  8. vue项目element-ui框架中的弹窗中的表单验证清除问题

    问题回顾: 1.vue项目的在弹窗上的form表单验证,第一次点击新增时正常,第二次新增打开弹窗后由于表单内容为空,出现验证这种情况 2.为了解决上面的情况,在执行点击新增事件加上this.$refs ...

  9. JS中的表单验证+正则表达式

    表单验证+正则表达式 一.非空验证 trim:去空格(去掉前后的空格),任何字符串都可以用这个方法.写法为:if(v.trim().length==0),表示如果去掉空格后的字符串的长度为0. < ...

  10. 模拟js中注册表单验证

    示例1 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

随机推荐

  1. 深入理解注解驱动配置与XML配置的融合与区别

    摘要:本文旨在深入探讨Spring框架的注解驱动配置与XML配置,揭示两者之间的相似性与差异. 本文分享自华为云社区<Spring高手之路2--深入理解注解驱动配置与XML配置的融合与区别> ...

  2. CMU15445 (Fall 2020) 数据库系统 Project#2 - B+ Tree 详解(上篇)

    前言 考虑到 B+ 树较为复杂,CMU15-445 将 B+ 树实验拆成了两部分,这篇博客将介绍 Checkpoint#1 部分的实现过程,搭配教材 <DataBase System Conce ...

  3. 如何洞察 C# 程序的 GDI 句柄泄露

    一:背景 1. 讲故事 前段时间有位朋友找到我,说他的程序界面操作起来很慢并且卡顿等一些不正常现象,从任务管理器看了下 GDI句柄 已经到 1w 了,一时也找不出什么代码中哪里有问题,让我帮忙看下,其 ...

  4. Devexpress如何获取RadioGroup选中项的值和显示值

    分享一个小技巧,如题目所示,DEV控件如何获取RadioGroup选中项的值和显示值.也是在网上找了很久,看了大家都是通过SelectIndex的值定位选中的按钮,并没有说取选中项的值,所以自己研究了 ...

  5. Taurus .Net Core 微服务开源框架:Admin 插件【1】 - 微服务节点管理

    前言: 最近发现 NetCore 的文章有点少,特来补几篇. 上一篇:Taurus.mvc .Net Core 微服务开源框架发布V3.1.7:让分布式应用更高效. 自上篇之后,期间更新了4个小版本, ...

  6. 基于DSP的设备振动信号的采集技术方案综述

    前记  在能源领域,由于很多地方都是无人值守,设备故障检测是一个必须面对的问题.笔者通过几个行业案例了解到,由于很多设备发生故障时候会产生特定频谱的声音,所以该行业对振动监测的需求特别强烈,由于涉及到 ...

  7. 从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生

    摘要:随着云计算的兴起和渗透,云数仓成为了数仓技术演进的新阶段,并且逐渐成为了众多企业的共同选择. 本文分享自华为云社区<从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生>,作 ...

  8. 浅谈REFS文件系统数据恢复研发经历(1)

    作为80后技术员, 我一直很喜欢李玟, 是我们那个时代的偶像, 一直也很喜欢听他的歌, 看到她的噩耗, 还是很那么的无法理解, 一个那么好的人怎么会得抑郁症呢, 心里多少还是无法接受. 不过联想到自己 ...

  9. ZEGO全新语音聊天室方案,2小时复刻 Clubhouse

    真的火了! 新晋带货王马斯克在 Clubhouse"开房"之后,直接让 Clubhouse 爆火出圈,据说,Clubhouse 平台邀请码现在在ebay上已经卖到了快200刀一个. ...

  10. ISP-AF相关-聚焦区域选择-清晰度评价

    1.镜头相关 镜头类型 变焦类型: 定焦.手动变焦.自动变焦 光圈: 固定光圈.手动光圈.自动光圈 视场角: 鱼眼镜头.超广角镜头.广角镜头.标准镜头.长焦镜头.超长焦镜头(由大至小) 光圈: 超星光 ...