学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(下)

 

        

在设计应用程序时,你应该保持对用户的不信任,虽然你在输入界面上提示了如何正确填写每个值的说明,但必须对他们输入的任何值进行校验。 Blazor 提供了一些简单的校验工具,接下来我们来学习如何配置表单中的输入项,以便正确地校验和响应用户数据。

验证用户的输入数据

当你收集用户的输入的信息时,必须检查其是否有意义且格式是否正确:

  • 出于业务原因:图书信息(例如价格或库存数量信息)必须正确无误才能为用户提供优质服务。例如,如果在界面中输入库存数量时能立即发现该数据是错误,则可以防止以后付出更高的代价。
  • 出于技术原因:如果代码使用表单输入进行计算或其他处理,则不正确的输入可能会导致错误和异常。
  • 出于安全原因:恶意用户可能会试图通过利用未检查的输入框进行代码注入攻击。

向表单增加校验功能

在软件开发中有一个重要的原则被称为 DRY(即“不要自我重复”)。 Blazor组件鼓励进行只需要开发一次,这个功能就能在整个应用中使用,不需要重复开发,或复制粘贴。 DRY 有助于减少应用中的代码量。 DRY 使代码更加不易出错,且更易于测试和维护。

Blazor组件和 Entity Framework框架提供的DRY原则级别的校验。校验规则在实体类中的某处以声明方式指定,且在应用程序的所有位置强制执行。

如果看过我的MVC系列,那么肯定了解一个有关校验特性的命名空间,System.ComponentModel.DataAnnotations,DataAnnotations 命名空间下提供一组内置的校验规则特性,我们可以通过声明的方式应用于类或属性之上。

DataAnnotations 命名空间下提供内置校验规则特性如下:

  • [ValidationNever]. 如果要确保该字段从不包含在验证中,请使用此特性。
  • [CreditCard]. 如果要记录用户的有效信用卡号,请使用此特性。
  • [Compare]. 如果要确保模型中的两个属性匹配,请使用此特性。
  • [Phone]. 如果要记录用户的有效电话号码,请使用此特性。
  • [RegularExpression]. 如果通过将值与正则表达式进行比较来检查值的格式,请使用此特性。
  • [StringLength]. 如果要检查字符串值的长度是否不超过最大长度,请使用此特性。
  • [Url]. 如果要记录用户的有效 URL,请使用此特性。
  • [Required]. 如果要求用户必须填写,请使用此特性。

让 ASP.NET Core Blazor 强制自动执行校验规则有助于提升应用程序的可靠性。 在实体类上进行自动校验助于保护应用程序,因为添加新代码时无需手动修改旧代码。不要想当然地认为用户知道所有信息:例如,并非每个人都知道有效电子邮件地址的格式。

在Visual Studio 2022的解决方案资源管理器中,打开 Models\Book.cs 文件。现在我们来给Book 类使用 Required、StringLength、RegularExpression 和 Range 校验规则特性,代码如下所示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks; namespace BlazorAppDemo.Models
{
public class Book {
private string name = String.Empty;
private string author=String.Empty; [Key]
public int ID { get; set; } [Required]
[StringLength(50)]
public string Name { get => name; set => name = value; }
public DateTime ReleaseDate { get; set; } [Required, StringLength(40)]
public string Author { get => author; set => author = value; } public decimal Price { get; set; } /// <summary>
/// 图书类型编号
/// </summary> [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$"), Required, StringLength(40)]
public string Type { get; set; } /// <summary>
/// 页码
/// </summary>
public int TotalPages { get; set; }
/// <summary>
/// 库存数量
/// </summary>
[Range(2,30)]
public int StockQty { get; set; } /// <summary>
/// 已租数量
/// </summary> public int Qty { get; set; } } }
       我们将在表单中使用此实体,校验特性应用在实体类的属性上,并且将前端强制执行。

Required 特性表示属性必须具有一个值。 但是,用户可以随时输入空格对可以为 null 的类型进行校验约束。从本质上来说,对于不能为 null 的值类型(如 decimal、int、float 和 DateTime),可以不添加 Required 特性。

RegularExpression 特性限制用户可以输入的字符。 在上述代码中, Type字母(禁用空格、数字和特殊字符)。

Range 特性将值限制在指定范围内。

StringLength 特性设置字符串的最大长度,且可视情况设置最小长度。

第八,在Visual Studio 2022的菜单栏上,找到“调试à开始调试”或是按F5键,Visual Studio 2022会生成BlazorAppDemo应用程序,并在浏览器中打开Home页面,我们使用鼠标点击左边的菜单栏上的“添加图书”菜单项,然后使用鼠标左键点击“保存”按钮,会出现一个错误,如下图。

从上图中看出,校验好像没有起作用就直接保存到数据库了,这是因为我们没有在EditForm中没有添加DataAnnotationsValidator组件。如果要显示校验不通过生成的提示消息,我们应该加一个ValidationSummary组件,这个组件用于显示表单中所有控件的有校验规则的提示消息集合。我们来修改一下组件的代码,具体代码如下。

<h3>AddBook</h3>

<EditForm Model=@addBook OnSubmit="Save">
<DataAnnotationsValidator />
<ValidationSummary /> <div>@Message</div> <p> 图书名称:
<InputText @bind-Value=addBook.Name></InputText>
</p> <p>作者:
<InputText @bind-Value=addBook.Author></InputText>
</p> <p>出版日期:
<InputDate @bind-Value=addBook.ReleaseDate></InputDate>
</p>
<p>价格: <InputNumber @bind-Value=addBook.Price></InputNumber>
</p>
<p>类型: <InputText @bind-Value=addBook.Type></InputText>
</p>
<p>总页数: <InputNumber @bind-Value=addBook.TotalPages></InputNumber>
</p>
<p>库存数量:
<InputNumber @bind-Value=addBook.StockQty></InputNumber>
</p> <p>已租数量:
<InputNumber @bind-Value=addBook.Qty></InputNumber>
</p>
<input type="submit" class="btn btn-primary" value="Save" />
</EditForm>

第九,在Visual Studio 2022的菜单栏上,找到“调试-->开始调试”或是按F5键,Visual Studio 2022会生成BlazorAppDemo应用程序,并在浏览器中打开Home页面,我们使用鼠标点击左边的菜单栏上的“添加图书”菜单项,然后使用鼠标左键点击“保存”按钮,由于我们没有输入正确的数据,校验组件将会提示我们要输入的数据。如下图。

Blazor的校验是在以下两个时间点上执行:

  • 当用户按 Tab 键离开某个字段时,将执行字段验证。 字段验证可确保用户及早了解验证问题。
  • 当用户提交表单时,将执行模型验证。 模型验证可确保不会存储无效数据。

如上图,表单验证失败,提示消息都显示在ValidationSummary,而没有显示在相应输入框的旁边。

如果想要将校验提示信息显示在输入框的旁边,需要在代码中添加 ValidationMessage 组件。如果你不想要Blazor提供的默认信息,你可以在实体类的每个属性的特性中找到一个ErrorMessage属性,这个属性就是用于自己定义一些校验提示消息,校验的提示消息尽可能的对用户有所帮助。代码如下所示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks; namespace BlazorAppDemo.Models
{ public class Book
{
private string name = String.Empty;
private string author=String.Empty; [Key]
public int ID { get; set; } [Required(ErrorMessage ="图书名称必须填写,图书名称不能超过50个字符。")] [StringLength(50)]
public string Name { get => name; set => name = value; } public DateTime ReleaseDate { get; set; }
[Required(ErrorMessage = "作者必须填写,作者名不能超过40个字符。"), StringLength(40)]
public string Author { get => author; set => author = value; } public decimal Price { get; set; }
/// <summary> /// 图书类型编号
/// </summary>
[RegularExpression(@"^[a-zA-Z]*$"), Required(ErrorMessage = "图书类型必须填写,而且只能是A-Z的字母,最少是一个字母,最多10个字母。"), MinLength(1),StringLength(10)] public string Type { get; set; }
/// <summary>
/// 页码
/// </summary>
public int TotalPages { get; set; } /// <summary>
/// 库存数量
/// </summary>
[Range(2,30,ErrorMessage = "图书库存数量在2至30之间。")] public int StockQty { get; set; }
/// <summary>
/// 已租数量
/// </summary>
public int Qty { get; set; } }
}

接下来我们来修改AddBook.razor组件的前端代码,将校验提示信息显示在输入框的旁边,在代码中添加ValidationMessage控件,将ValidationMessage控件的For属性与实体对象的相对应的属性相关联。代码如下所示。

<h3>AddBook</h3>

<EditForm Model=@addBook OnSubmit="Save">
<DataAnnotationsValidator />
<ValidationSummary /> <div>@Message</div>
<p> 图书名称:
<InputText @bind-Value=addBook.Name></InputText>
<ValidationMessage For="@(() => addBook.Name)" />
</p>
<p>作者:
<InputText @bind-Value=addBook.Author></InputText>
<ValidationMessage For="@(() => addBook.Author)" />
</p> <p>出版日期:
<InputDate @bind-Value=addBook.ReleaseDate></InputDate>
</p>
<p>价格: <InputNumber @bind-Value=addBook.Price></InputNumber>
</p>
<p>类型:
<InputText @bind-Value=addBook.Type></InputText>
<ValidationMessage For="@(() => addBook.Type)" />
</p> <p>总页数:
<InputNumber @bind-Value=addBook.TotalPages></InputNumber>
</p>
<p>库存数量:
<InputNumber @bind-Value=addBook.StockQty></InputNumber>
<ValidationMessage For="@(() => addBook.StockQty)" />
</p>
<p>已租数量:
<InputNumber @bind-Value=addBook.Qty></InputNumber>
</p>
<input type="submit" class="btn btn-primary" value="Save" /> </EditForm>

第十,在Visual Studio 2022的菜单栏上,找到“调试à开始调试”或是按F5键,Visual Studio 2022会生成BlazorAppDemo应用程序,并在浏览器中打开Home页面,我们使用鼠标点击左边的菜单栏上的“添加图书”菜单项,然后使用鼠标左键点击“保存”按钮,由于我们没有输入正确的数据,校验组件将会提示我们要输入的数据。如下图。

学习ASP.NET Core Blazor编程系列八——数据校验的更多相关文章

  1. 学习ASP.NET Core Blazor编程系列九——服务器端校验

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  2. 学习ASP.NET Core Blazor编程系列十——路由(上)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  3. 学习ASP.NET Core Blazor编程系列十——路由(中)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  4. C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理

    C#编译器优化那点事   使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...

  5. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(上)

    学习ASP.NET Core Blazor编程系列一--综述 一.概述 Blazor 是一个生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 U ...

  6. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...

  7. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(下)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  8. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(完)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  9. 022年9月12日 学习ASP.NET Core Blazor编程系列三——实体

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

随机推荐

  1. 技术分享 | 浅谈mysql语法解析调试方法

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 本文向您介绍一种利用mysql解析器和bison的调试选项进行sql语法解析跟踪 ...

  2. Luogu3871 [TJOI2010]中位数 (平衡树)

    "#define int long long" 导致100pts \(\rightarrow\) 80pts #include <iostream> #include ...

  3. 清晰梳理最全日志框架关系与日志配置-SpringBoot 2.7.2 实战基础

    优雅哥 SpringBoot 2.7.2 实战基础 - 07 - 日志配置 Java 中日志相关的 jar 包非常多,log4j.log4j2.commons-logging.logback.slf4 ...

  4. ArkUI block 标签

    block 标签在构建时不会被当作真实 DOM,而 block 标签之下的标签都会被渲染到真实 DOM 中.它类似于 Vue 的 template 标签. <div class="co ...

  5. 没有二十年功力,写不出Thread.sleep(0)这一行“看似无用”的代码!

    你好呀,我是喜提七天居家隔离的歪歪. 这篇文章要从一个奇怪的注释说起,就是下面这张图: 我们可以不用管具体的代码逻辑,只是单单看这个 for 循环. 在循环里面,专门有个变量 j,来记录当前循环次数. ...

  6. electron 起步

    electron 起步 为什么要学 Electron,因为公司需要调试 electron 的应用. Electron 是 node 和 chromium 的结合体,可以使用 JavaScript,HT ...

  7. opencv videocapture

    import time import cv2 import numpy as np from os import path import pickle ''' 关于camera id 此处需要稍微说几 ...

  8. 2.第一篇 k8s组件版本及功能简介

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483772&idx=1&sn=a693d8a9 ...

  9. 使用docker-compose运行nginx容器挂载时遇到的文件/目录问题

    单独使用docker run命令指定挂载文件路径运行nginx容器是可以的,但是用在docker-compose中就不行了 报错如下: 原因就是挂载出错,不能直接挂载文件,还有挂载的容器里的目录要正确 ...

  10. 使用 kubectl 执行 Rolling Update(滚动更新)

    Rolling Update滚动更新 通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,从而实现零停机.新的 Pod 将在具有可用资源的 Node(节点)上进行 ...