ASP.NET MVC 5 - 给数据模型添加校验器

ASP.NETUI控件(FineUI)V4.2.2官方中文专业版 支持一个面板拥有多个工具栏。 -增加示例:其他控件->工具栏与菜单->多行工具栏。 -增加示例:表格控件->分页与排序->数据库分页(底部工具栏)。 重构表单改变确认对话框(不兼容提醒!)。 -删除Window控件的EnableConfirmOnClose属性,以及GetConfirmHideReference类似的5个方法。 -删除ActiveWind 立即下载

在本节中将会给Movie模型添加验证逻辑。并且确保这些验证规则在用户创建或编辑电影时被执行。

拒绝重复 DRY

ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY --Don’t Repeat Yourself)"。ASP.NET MVC鼓励您指定功能或者行为,只做一次,然后将它应用到应用程序的各个地方。这可以减少您需要编写的代码量,并减少代码出错率,易于代码维护。

给ASP.NET MVC 和 Entity Framework Code First 提供验证支持是 DRY 信条的一次伟大实践。您可以在一个地方 (模型类) 中以声明的方式指定验证规则,这个规则会在应用程序中的任何地方执行。

让我们看看您如何在本电影应用程序中,使用此验证支持。

给电影模型添加验证规则

您将首先向Movie类添加一些验证逻辑。

打开Movie.cs 文件,注意到System.Web 命名空间并未包含System.ComponentModel.DataAnnotations. DataAnnotations提供了一组内置的严重属性,可供您应用于类、属性。(DataAnnotations也包含一个DataType属性,来帮助格式化的办法来校验)

更新Movie类,以利用内置的Required、 StringLength, RegularExpression和Range验证属性。以下面的代码为例,以应用验证属性。

public class Movie

{

public int ID { get; set; }

[StringLength(60, MinimumLength = 3)]

public string Title { get; set; }

[Display(Name = "Release Date")]

[DataType(DataType.Date)]

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

public DateTime ReleaseDate { get; set; }

[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]

[Required]

[StringLength(30)]

public string Genre { get; set; }

[Range(1, 100)]

[DataType(DataType.Currency)]

public decimal Price { get; set; }

[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]

[StringLength(5)]

public string Rating { get; set; }

}

 

在StringLength属性设置字符串的最大长度,它会在数据库上设置此限制,因此的数据库schema将发生变化。右键单击电影表, 在服务器资源管理器(Server  explorer),然后单击打开表定义(Open Table Definition):

clip_image002

在上面的图片中,你可以看到所有的字符串字段被设置为了NVARCHAR  (MAX)数据类型.  我们将使用迁移来更新架构。生成解决方案,然后打开软件包管理器控制台(the Package Manager Console ),输入如下命令:

add-migration DataAnnotations
update-database

当这个命令完成后,Visual Studio将打开类代码文件,它定义了新DbMIgration派生类(DataAnnotations),你可以在Up方法看到更新架构约束代码如下所示:

public override void Up()

{

AlterColumn("dbo.Movies", "Title", c => c.String(maxLength: 60));

AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false, maxLength: 30));

AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5));

}

 

该流派(Genre)字段不再可为Null(也就是说,你必须输入一个值)。该评级(Rating)字段最大长度为5, 标题的最大长度为60。标题(Title )和价格 (Price)的范围的最小长度并没有更改。

请在数据库中,检查电影表的schema:

clip_image004

该字符串字段显示新的长度限制和流派字段(Genre)不能再为空。

验证属性指明您想要应用到模型属性的行为。Required 和MinimumLength属性指出某一属性不可为空,但没有什么能够阻止用户输入空格来验证。该RegularExpression属性是用来限制哪些字符可以输入。在上面的代码中,流派(Genre)和等级(Rating)只能使用字母(空格,数字和特殊字符是不允许的)。该范围(Range )属性约束的值在一个指定范围内。在StringLength 属性允许您设置一个字符串属性的最大长度,以及最小长度(可选的)。值类型(decimal, int, float, DateTime)有固有必需设置的,不需要的Required属性。

Code First确保你的模型在指定class上在验证规则强制执行之前应用程序将变更储存在数据库中。例如,下面的代码将抛出一个DbEntityValidationException 异常时,调用SaveChanges方法时,因为几个必要的Movie属性缺少:

MovieDBContext db = new MovieDBContext();

Movie movie = new Movie();

movie.Title = "Gone with the Wind";

db.Movies.Add(movie);

db.SaveChanges(); // <= Will throw server side validation exception

 

上面的代码会抛出以下异常:

Validation failed for one or more entities. 参阅  'EntityValidationErrors' 属性获得更多信息.

具有通过.NET Framework会自动强制执行的验证规则, 有助于使你的应用程序更加健壮。它还确保可以不会忘记验证的东西,即在不经意间不会让坏的数据写入数据库。

ASP.NET MVC 的验证错误UI

重新运行应用程序,浏览 /Movies的 URL。

单击Create New链接,来添加一部新电影。在窗体中填写一些无效值,然后单击Create按钮。

如同jQuery的客户端验证来检测到错误时,它会显示一个错误消息。

注意,为了使jQuery支持使用逗号的非英语区域的验证 ,需要设置逗号(",")来表示小数点,如本教程前面所述, 你须引入NuGet globalize。请注意,表单在每一个相应的验证错误消息旁边,已经自动使用红色边框的颜色突出显示文本框指明无效数据。这些错误是强制执行了客户端端(使用JavaScript和jQuery)和服务器端(如果用户禁用了JavaScript)。

一个真正的好处是,你并不需要更改MoviesController类或Create.cshtml视图中的一行代码,来启用此验证的用户界面。您在前面教程所创建的控制器和视图会自动启用,使用验证指明的Movie model类的属性。使用Edit行为方法,同样的验证方法也完全适用。直到没有任何客户端验证错误的表单数据,才会被发送回服务器。您可以通过在HTTP POST方法,用一个断点来验证这一点; 或通过使用fiddler tool,或者IE浏览器F12 developer tools。

如何验证创建视图和创建方法

您可能很想知道验证用户界面在没有更新控制器或视图代码的情况下是如何生成的。下面列出了MovieController类中的Create方法。它们是之前教程中自动生成的,并没有修改。

public ActionResult Create()

{

return View();

}

// POST: /Movies/Create

// To protect from overposting attacks, please enable the specific properties you want to bind to, for

// more details see http://go.microsoft.com/fwlink/?LinkId=317598.

[HttpPost]

[ValidateAntiForgeryToken]

public ActionResult Create([Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)

{

if (ModelState.IsValid)

{

        db.Movies.Add(movie);

        db.SaveChanges();

return RedirectToAction("Index");

}

return View(movie);

}

 

第一种(HTTP GET)Create 方法用来显示初始的创建form。第二个 ([HttpPost]) 方法处理form的请求。第二种Create方法 (HttpPost 版本) 调用 ModelState.IsValid来检查是否有任何的Movie验证错误。调用此方法将验证对象上所有应用了验证约束的属性。如果对象含有验证错误,则Create方法会重新显示初始的form。如果没有任何错误,方法将保存信息到数据库。在我们的电影示例中,我们使用了验证,当客户端检测到错误时,form不会被post到服务器;所以第二个Create方法永远不会被调用。如果您在浏览器中禁用了 JavaScript,客户端验证也会被禁用,HTTP POST Create方法会调用 ModelState.IsValid来检查影片是否含有任何验证错误。

您可以在HttpPost Create方法中设置一个断点,当客户端验证检测到错误时,不会post form数据,所以永远不会调用该方法。如果您在浏览器中禁用 JavaScript,然后提交具有错误信息的form,断点将会命中。您仍然得到充分的验证,即使在没有 JavaScript的情况下。

下图显示了如何禁用 Internet Explorer 中的 JavaScript。

clip_image008

clip_image010

下图显示了如何在火狐浏览器中禁用 JavaScript。

clip_image012

下图显示了如何在 Chrome 浏览器中禁用 JavaScript。

clip_image014

下面是框架代码在之前的教程中生成的Create.cshtml视图模板。它用来为以上两个操作方法来显示初始的form,同时在验证出错时来重新显示视图。

@model MvcMovie.Models.Movie

@{

    ViewBag.Title = "Create";

}

<h2>Create</h2>

@using (Html.BeginForm())

{

    @Html.AntiForgeryToken()   

<div class="form-horizontal">

<h4>Movie</h4>

<hr />

        @Html.ValidationSummary(true)

<div class="form-group">

            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })

<div class="col-md-10">

                @Html.EditorFor(model => model.Title)

                @Html.ValidationMessageFor(model => model.Title)

</div>

</div>

        @*Fields removed for brevity.*@       

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Create" class="btn btn-default" />

</div>

</div>

</div>

}

<div>

    @Html.ActionLink("Back to List", "Index")

</div>

@section Scripts {

    @Scripts.Render("~/bundles/jqueryval")

}

 

请注意,代码如何使用Html.EditorFor helper 输出为Movie中的每个属性的<input>元素。此Helper旁边是对Html.ValidationMessageFor方法的调用。这两个Helper方法将处理由控制器传递到视图的模型对象(在这里是,Movie对象)。它们会自动查找模型中指定的验证属性,并显示适当的错误消息。

如果您想要在后面更改验证逻辑,您可以做在一个地方,将验证信息添加到模型上。 (此示例中,是movie 类)。您不必担心不符合规则 ,验证逻辑会在应用程序的不同部分执行——在一个地方定义验证逻辑将会被使用到各个地方。这使代码非常干净,并使它易于维护和扩展。它意味着您会完全遵守DRY原则。

使用DataType属性

打开Movie.cs文件并检查Movie类。在System.ComponentModel.DataAnnotations命名空间提供的格式化(formatting)属性,除了内置的一套验证的属性。我们已经应用了的DataType枚举值的ReleaseDate和Price 字段。下面的代码显示了ReleaseDate和Price 用适当的的DataType属性。

[DataType(DataType.Date)]

public DateTime ReleaseDate { get; set; }

[DataType(DataType.Currency)]

public decimal Price { get; set; }

该DataType属性只提供提示的视图引擎对数据进行格式化(与相应的属性,如<a>取代的URL及 <a href="mailto:EmailAddress.com">取代电子邮件。您可以使用RegularExpression的属性来验证数据格式。DataType属性用于指定一个比数据库内部类型更加具体的一种数据类型,但它们不是验证属性。在这种情况下,我们只需要保留的日期跟踪,而不是日期和时间。该枚举的DataType提供了多种数据类型,如Date, Time,  PhoneNumber, Currency, EmailAddress 和其他更多的。该的DataType 的属性也可以使应用程序来自动提供特定类型的功能。例如,一个mailto:链接可以DataType.EmailAddress创建和日期选择器可以在支持HTML5的浏览器提供的DataType.Date。该数据类型属性发出的HTML5data-(发音读数据破折号)属性与HTML5的浏览器可以理解。 该DataType 属性不提供任何验证。

DataType.Date并未指定显示的日期格式。默认情况下,根据基于服务器的的CultureInfo预设格式显示数据字段。

该DisplayFormat的属性是用来显式地指定日期格式的:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

public DateTime EnrollmentDate { get; set; }

该ApplyFormatInEditMode设置指定了当值进行编辑显示在一个文本框中,格式化亦应适用。 (您可能不希望这样的某些字段 - 例如货币值,你可能不希望在编辑文本框中出现货币符号。)

你可以单独使用DisplayFormat属性;但和DataType属性一起,通常是一个好主意。该DataType 属性传递数据的语义,而不是如何呈现它在屏幕上,并具有以下的优点,不带DisplayFormat的:

· 浏览器可以使HTML5的功能(例如显示一个日历控件,在区域设置相应的货币符号,电子邮件中的链接,等等)。

· 默认情况下,浏览器就会使用基于语言环境(locale)的正确格式呈现数据。

· 在的DataType属性可以使MVC选择合适的字段模板以呈现数据(如果本身所使用的的DisplayFormat使用字符串模板)。欲了解更多信息,请参阅see Brad  Wilson's的ASP.NET MVC 2 Templates。 (虽然写的MVC2,本文仍然适用于ASP.NET MVC 5的当前版本。)

如果你使用了的DataType的属性具有一个日期字段,你也必须指明,以确保字段正确地呈现Chrome浏览器中的DisplayFormat属性。欲了解更多信息,请参阅this StackOverflow thread。

注:jQuery的验证不与Range属性和DateTime的同时工作。例如,下面的代码总是显示一个客户端验证错误,即使当日期是在指定的范围内:

[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]

你可能会禁用jQuery的日期校验,而使用带有的Range属性DateTime。这通常不是一个好的做法,在你的模型里,编译器很难确定日期,所以使用Range属性和DateTime效果不好。

下面的代码显示在同一行合并属性:

public class Movie

{

public int ID { get; set; }

[Required,StringLength(60, MinimumLength = 3)]

public string Title { get; set; }

[Display(Name = "Release Date"),DataType(DataType.Date)]

public DateTime ReleaseDate { get; set; }

[Required]

public string Genre { get; set; }

[Range(1, 100),DataType(DataType.Currency)]

public decimal Price { get; set; }

[Required,StringLength(5)]

public string Rating { get; set; }

}

 

在教程的下一部分,我们先会看看代码,然后再改进一下自动生成的Details 和 Delete 方法。

-----------------------------------------------------------------------------------------

《ASP.NET MVC 5 入门指南》12篇文章汇总如下:

1. ASP.NET MVC 5 - 开始MVC 5之旅

2. ASP.NET MVC 5 - 控制器

3. ASP.NET MVC 5 - 视图

4. ASP.NET MVC 5 - 将数据从控制器传递给视图

5. ASP.NET MVC 5 - 添加一个模型

6. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB

7. ASP.NET MVC 5 - 从控制器访问数据模型

8. ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

9. ASP.NET MVC 5 - 给电影表和模型添加新字段

10. ASP.NET MVC 5 - 给数据模型添加校验器

11. ASP.NET MVC 5 - 查询Details和Delete方法

12. ASP.NET MVC 5 - 使用Wijmo MVC 5模板1分钟创建应用

 

希望这些文章对感兴趣的朋友有所帮助,另附上PDF版的汇总文档:

《ASP.NET MVC 5 入门指南》PDF版

APS.NET+FineUI常用框架(初学者适用) FineUI在vs2017中的配置,里面有官网一个现成的框架,初学者不会配置的可以看看 立即下载

相关推荐

C++ muduo网络库知识分享01 - Linux平台下muduo网络库源码编译安装

Muduo is a multithreaded C++ network library based on the reactor pattern. muduo库的介绍就是:一个基于reactor反应堆模型的多线程C++网络库。 muduo网络库是C++语言开发的一个非常优秀的网络库,作者陈硕,muduo网络库在多线程环境下性能非常高,该系列文章会分享一些muduo库源码的知识,包括它的线程池源码...

大秦坑王的专栏 3万+

ASP.NET MVC5中的Model验证

Model验证是ASP.NET MVC中的重要部分,它主要用于判断输入的数据类型及值是否符合我们设定的规则,这篇文章就介绍下ASP.NET MVC中Model验证的几种方式。 后台验证 DataAnnotation ValidationAttribute IValidatableObject IDataErrorInfo 前端验证 后台验证 DataAnnotation DataAnn...

milijiangjun的博客 991

从AMCL到SLAM Toolbox:在Nav2中实现高精度纯定位的实践指南

本文详细介绍了从AMCL迁移到SLAM Toolbox纯定位模式的实践指南,帮助开发者在Nav2中实现高精度定位。通过对比AMCL与SLAM Toolbox的性能差异,提供环境配置、参数调优、Nav2集成等关键步骤,显著提升机器人在动态环境中的定位精度和重定位效率。

weixin_29292535的博客 147

ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图。但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好。打开Models \ Movie.cs文件,并添加高亮行如下所示: using System; using System.ComponentModel.DataAnnotations; using Sys...

476

贝叶斯神经网络(Bayesian Neural Network)

最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。

梁小憨憨的博客 3653

LabVIEW与MySQL实时数据存储:传感器采集与数据库同步实践

本文详细介绍了如何将LabVIEW与MySQL结合,实现传感器数据的实时采集与高效存储。通过设计合理的数据库表结构、配置LabVIEW数据库连接工具包,并编写核心的采集与存储VI,构建了稳定可靠的数据链路。文章重点分享了批量插入、连接管理、时间同步等关键优化技巧与避坑指南,帮助工程师应对工业监控、环境监测等场景下的实时数据同步挑战。

weixin_29281915的博客 261

从‘计算器语法’入手:5步用C语言实现你的第一个递归下降语法分析程序

本文详细介绍了如何使用C语言实现递归下降语法分析程序,从计算器语法入手,通过5个步骤构建一个能处理加减乘除和括号的计算器。文章涵盖了语法规则定义、C语言项目框架搭建、词法分析器实现、递归下降解析器编写以及错误处理,适合编译原理初学者快速上手。

weixin_33727510的博客 514

ENVI哨兵一号数据处理

使用ENVI+SarScape处理哨兵数据

Rjjjjj11的博客 2万+

Asp.Net - MVC-5.模型绑定与验证

使用模型获取绑定数据: Person类; public class Person { public string ID { get; set; } public string Name { get; set; } public string Num { get; set; } } <body> <h1>个人信息</h1> @using (Html.BeginForm()) .

qq_59534628的博客 291

5G NR LDPC码(2)—— 从基图到速率匹配:解码5G高速数据信道的标准化设计

本文深入解析了5G NR LDPC码的标准化设计流程。从作为核心骨架的基图(BG1/BG2)出发,详细阐述了其如何通过扩展因子Z灵活生成实际校验矩阵,并协同传输块大小计算与分段策略。文章重点剖析了基于循环缓存和冗余版本的速率匹配机制,以及其如何高效支撑增量冗余混合自动重传请求,从而确保5G高速数据信道在复杂环境下的可靠与高效传输。

weixin_29206669的博客 271

Gartner《构建可扩展数据产品建设框架》心得

数据产品化:从概念到落地的实践指南 当前企业正从传统数据需求模式转向数据产品化新范式。本文系统阐述了数据产品的核心价值、定义分类和实施框架,指出成功关键是将数据包装为可复用、可扩展的产品。Gartner框架强调产品思维,提出4阶段12步实施路径,涵盖设计、工程、发布和监控全流程。文章特别提醒要避免7大常见误区,如简单重命名报表、忽视元数据治理等,建议采取MVP策略,90天内完成从价值验证到产品落地的闭环。实施中需平衡技术选型与业务需求,建立跨职能团队,并通过AARRR模型持续追踪产品价值。

2501_91410404的博客 1002

[转]ASP.NET MVC 5 - 给数据模型添加校验器

在本节中将会给Movie模型添加验证逻辑。并且确保这些验证规则在用户创建或编辑电影时被执行。 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY --Don’t Repeat Yourself)"。ASP.NET MVC鼓励您指定功能或者行为,只做一次,然后将它应用到应用程序的各个地方。这可以减少您需要编写的代码量,并减少代码出错率,易于代码维护。 ...

weixin_33734785的博客 107

Xilinx系FPGA学习笔记(三)Vivado的仿真及ILA使用

接着学习vivado的使用方法。

贾saisai的博客 2546
上一篇: 程序员级别鉴定书(.NET面试问答集锦)
下一篇: 应用系统中常见报表类型解析
ComponentOne服务团队
博客等级 码龄12年 5粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值