什么是模型验证? 模型验证是给模型属性提供一种规则,并且可以验证模型属性的值,以至于他们是合法的,如果这些值不合法,给客户显示一些容易理解的错误并且帮助客户修改正这个问题
模型验证分为两类:
1 服务器端验证
2 客户端验证
什么是ModelState ? ModelState 是一个键值对的集合包含了模型绑定和验证过程中发生的错误,例如-使用一个字符串类型值赋值给Int整数类型 ,ModelState 将会给予一个错误
AddModelError(property, message);
property –实体类的一个属性
1.2 ModelState.IsValid属性
如果模型类中所有的属性的值都可用,ModelState.IsValid返回true,即在ModelState中有错误, 返回false,我们在IF ELSE 代码块如下:
if (ModelState.IsValid)
{
... do something
}
else
{
... do something
}
2 模型验证的例子
因此,首先使用下面代码创建一个JobApplication.cs 类 在应用程序Models文件夹下
namespace AspNetCore.ModelValidation.Models
{
public class JobApplication
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public string Sex { get; set; }
public string Experience { get; set; }
public bool TermsAccepted { get; set; }
}
}
JobApplication类定义了不同的属性,为我们模型验证做测试,创建2个视图在Views->job 文件夹下,他们分别是:
@model JobApplication
@{
ViewData["Title"] = "Job Application";
}
<h2>Job Application</h2>
<form class="m-1 p-1" method="post">
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Name" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="Name" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="DOB" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="DOB" type="text" asp-format="{0:d}" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Sex" class="control-label"></label>
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="M" class="form-check" />男
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="F" class="form-check" />女
</div>
<div class="col-sm-9">
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Experience" class="control-label"></label>
</div>
<div class="col-sm-11">
<select asp-for="Experience" class="form-control">
<option value="选择">选择</option>
<option value="0">新手</option>
<option value="1">0-1 年</option>
<option value="2">1-2 年</option>
<option value="3">2-3 年</option>
<option value="4">3-4 年</option>
<option value="5">4-5 年</option>
</select>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
</div>
<div class="col-sm-1">
<input asp-for="TermsAccepted" class="form-label" />
</div>
<div class="col-sm-10">
<label asp-for="TermsAccepted" class="form-check-label">
我接受条款 & 条件
</label>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-11 offset-sm-1">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
这个视图包含一个Job申请表单,用户填充详细信息并且通过点击Submit提交表单
@model JobApplication
@{
Layout = "_Layout";
ViewData["Title"] = "接受";
}
<h2>接受</h2>
<table class="table table-bordered">
<tr>
<th>姓名:</th>
<td>@Model.Name</td>
</tr>
<tr>
<th>出生日期:</th>
<td>@Model.DOB.ToString("d")</td>
</tr>
<tr>
<th>性别:</th>
<td>@Model.Sex</td>
</tr>
<tr>
<th>工作经验:</th>
<td>@Model.Experience</td>
</tr>
<tr>
<th>条款:</th>
<td>@Model.TermsAccepted</td>
</tr>
</table>
<a class="btn btn-success" asp-action="Index">返回</a>
用户提交的数据将呈现Accepted视图table内,HTTP POST版本的Index方法通过模型绑定技术接受用户在表单中填充的值,代码如下:
using AspNetCore.ModelValidation.Models;
using Microsoft.AspNetCore.Mvc;
namespace AspNetCore.ModelValidation.Controllers
{
public class JobController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(JobApplication jobApplication)
{
return View("Accepted", jobApplication);
}
}
}
现在运行应用程序并且进入URL – /Job,你将发现Job申请表单,这个表单看上去很Nice,但是没有做模型验证
将下面值输入到控件中:
1. 姓名– Donald
2. 出生日期– 12-24-1986
3. 性别– 不输入任何值,保持原样
4. 经验– 不输入任何值,保持原样
5. 我接受条款和条件 –不输入任何值,保持原样
using AspNetCore.ModelValidation.Models;
using Microsoft.AspNetCore.Mvc;
namespace AspNetCore.ModelValidation.Controllers
{
public class JobController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(JobApplication jobApplication)
{
if (string.IsOrEmpty(jobApplication.Name))
ModelState.AddModelError(nameof(jobApplication.Name), "请输入用户名");
if (jobApplication.DOB == Convert.ToDateTime("01-01-0001 00:00:00"))
ModelState.AddModelError(nameof(jobApplication.DOB), "请输入出生日期");
else if (jobApplication.DOB > DateTime.Now)
ModelState.AddModelError(nameof(jobApplication.DOB), "出生日期不能大于当前时间");
else if (jobApplication.DOB < new DateTime(1980, 1, 1))
ModelState.AddModelError(nameof(jobApplication.DOB), "出生日期不能在1980年以前");
if (string.IsOrEmpty(jobApplication.Sex))
ModelState.AddModelError(nameof(jobApplication.Sex), "请选择性别");
if (jobApplication.Experience.ToString() == "Select")
ModelState.AddModelError(nameof(jobApplication.Experience), "请选择工作经验");
if (!jobApplication.TermsAccepted)
ModelState.AddModelError(nameof(jobApplication.TermsAccepted), "必须接受条款");
if (ModelState.IsValid)
return View("Accepted", jobApplication);
else
return View();
}
}
}
2.2 姓名属性
代码-if (string.IsOrEmpty(jobApplication.Name)) 检查 如果用户没有在name控件中填充名字,在这种情况下,代码- ModelState.AddModelError(nameof(jobApplication.Name), "请输入用户名");将执行,我们把验证姓名属性时发生的错误记录在ModelState
2.3 出生日期属性
if (string.IsOrEmpty(jobApplication.Sex))
这种情况下,Sex 属性验证的错误消息会被记录到ModelState中,通过下面代码
ModelState.AddModelError(nameof(jobApplication.Sex), "请选择性别");
2.5 经验属性
在razor视图中提供了工作经验选择下拉框,默认值是Select,因此代码
if (jobApplication.Experience.ToString() == "Select")
如果用户没有选择对应的接受条款,将会在ModelState中针对这个属性记录一条错误,代码-if (!jobApplication.TermsAccepted) ,最后,我们使用代码-ModelState.IsValid 做判断,当没有任何错误发生时,我们将返回接受视图并且提供jobApplication对象作为模型,如果ModelState.IsValid 返回false,那意味模型验证没有通过,因此我们能仅仅返回相同的视图,用户将看到错误,提示用户修改值
下面代码检查ModelState:
if (ModelState.IsValid)
return View("Accepted", jobApplication);
else
return View();
下面代码将在视图显示未验证的错误
3 检查HTML控件的形态
验证检查失败时模型绑定会为HTML控件添加名字为input-validation-error的CSS类,打开URL - /Job 在表单没有填充任何值时点击提交按钮
现在,我们通过浏览器来检查一下HTML表单中的Name控件,我们使用浏览器的开发工具来做这个工作
我们注意到它包含这个样式类- input-validation-error 代码如下:
<input class="form-control" type="text" data-val="true" data-val-required="The 姓名 field is required." id="Name" name="Name" value="">
没有通过验证时,我们将发现在所有控件上都添加了input-validation-error css,我们使用CSS样式在控件边框上添加红色,因此,在JobController的Index视图中添加样式代码块
@model JobApplication
@{
ViewData["Title"] = "Job Application";
}
<style>
.input-validation-error {
border-color: red;
}
</style>
<h2>Job Application</h2>
<form class="m-1 p-1" method="post">
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Name" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="Name" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="DOB" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="DOB" type="text" asp-format="{0:d}" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Sex" class="control-label"></label>
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="M" class="form-check" />男
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="F" class="form-check" />女
</div>
<div class="col-sm-9">
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Experience" class="control-label"></label>
</div>
<div class="col-sm-11">
<select asp-for="Experience" class="form-control">
<option value="Select">选择</option>
<option value="0">新手</option>
<option value="1">0-1 年</option>
<option value="2">1-2 年</option>
<option value="3">2-3 年</option>
<option value="4">3-4 年</option>
<option value="5">4-5 年</option>
</select>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
</div>
<div class="col-sm-1">
<input asp-for="TermsAccepted" class="form-label" />
</div>
<div class="col-sm-10">
<label asp-for="TermsAccepted" class="form-check-label">
我接受条款 & 条件
</label>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-11 offset-sm-1">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
4 使用asp-validation-summary显示错误
@model JobApplication
@{
ViewData["Title"] = "Job Application";
}
<style>
.input-validation-error {
border-color: red;
}
</style>
<h2>Job Application</h2>
<div asp-validation-summary="All" class="text-danger"></div>
<form class="m-1 p-1" method="post">
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Name" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="Name" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="DOB" class="control-label"></label>
</div>
<div class="col-sm-11">
<input asp-for="DOB" type="text" asp-format="{0:d}" class="form-control" />
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Sex" class="control-label"></label>
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="M" class="form-check" />男
</div>
<div class="col-sm-1">
<input asp-for="Sex" type="radio" value="F" class="form-check" />女
</div>
<div class="col-sm-9">
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
<label asp-for="Experience" class="control-label"></label>
</div>
<div class="col-sm-11">
<select asp-for="Experience" class="form-control">
<option value="Select">选择</option>
<option value="0">新手</option>
<option value="1">0-1 年</option>
<option value="2">1-2 年</option>
<option value="3">2-3 年</option>
<option value="4">3-4 年</option>
<option value="5">4-5 年</option>
</select>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-1">
</div>
<div class="col-sm-1">
<input asp-for="TermsAccepted" class="form-label" />
</div>
<div class="col-sm-10">
<label asp-for="TermsAccepted" class="form-check-label">
我接受条款 & 条件
</label>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-11 offset-sm-1">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
asp-validation-summary帮助标签会创建一个div把错误信息显示在该元素内,text-danger是Bootstrap的样式会给文本添加红色
再次运行你的应用程序并且在控件中不要输入任何值,提交表单,我们将会看到错误消息列表,如下图所示
asp-validation-summary属性可以设置3个值,分别是
名称 | |
<span asp-validation-for="Name"></span>
我们给每个属性都添加一个span 控件,需要修改一下span 标签的属性name – asp-validation-for="property"
@model JobApplication
@{
Layout = "_Layout";
ViewData["Title"] = "Job Application";
}
<style>
.input-validation-error {
border-color: red;
}
</style>
<h2>Job Application</h2>
<div asp-validation-summary="All" class="text-danger"></div>
<form class="m-1 p-1" method="post">
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DOB"></label>
<input asp-for="DOB" type="text" asp-format="{0:d}" class="form-control" />
<span asp-validation-for="DOB" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Sex"></label>
<div>
<input asp-for="Sex" type="radio" value="M" />Male
<input asp-for="Sex" type="radio" value="F" />Female
</div>
<span asp-validation-for="Sex" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Experience"></label>
<select asp-for="Experience" class="form-control">
<option value="Select">Select</option>
<option value="0">Fresher</option>
<option value="1">0-1 years</option>
<option value="2">1-2 years</option>
<option value="3">2-3 years</option>
<option value="4">3-4 years</option>
<option value="5">4-5 years</option>
</select>
<span asp-validation-for="Experience" class="text-danger"></span>
</div>
<div class="form-group">
<input asp-for="TermsAccepted" />
<label asp-for="TermsAccepted" class="form-check-label">
I accept the terms & conditions
</label>
<span asp-validation-for="TermsAccepted" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Submit Application</button>
</form>
再次运行应用程序,在没有输入任何值时提交表单,这次你将看到单个错误消息显示在每个控件的旁边,下面图片显示错误消息:
源代码地址
参考文献
https://www.yogihosting.com/aspnet-core-model-validation/#custom-model-validation
本文暂时没有评论,来添加一个吧(●'◡'●)