2.创建一个简单的数据录入应用程序

  • 时间:2019-05-29
  • 作者:Charles
  • 热度:4135

本文通过建立一个简单的数据录入应用程序,来考察MVC的更多特性。

一:设置场景

假设一个朋友要举行一个晚会,需要创建一个Web网站,以便让被邀请人在线电子回复。这个网站需要以下关键特性:

一个显示此晚会信息的主页;

一个可以用来进行RSVP(电子回复)的表单;

对RSVP表单数据进行验证,它将显示一个“谢谢你”的页面;

当完成RSVP时,给晚会的主人发送一份电子邮件。

根据前文所述,新建一个MVC项目,命名为“PartyInvites”,修改首页视图文件,如下图。

启动调试,在浏览器中将会看到晚会信息的主页,如下图。

二:设计一个数据模型

在MVC中,M代表模型(Model)时应用程序最重要的部分。模型时应用程序主体(称为域,Domain)所定义的现实对象、过程以及规则的表示。模型,通常称为域模型(Domain Model),含有应用程序域中要建立的C#对象,成为域对象(Domain Object)。这些域对象构成了整个应用程序的体系,以及操纵这些对象的方法。视图和控制器以一种一致的方法把这个域暴露给客户端。一个设计良好的MVC应用程序,必须从设计良好的模型开始,它是随后添加控制器和视图的焦点。

对于PartyInvites应用程序,不需要复杂的模型,因此将创建一个域类,叫做GuestResponse,这个对象将负责存储,验证并确认RSVP。

添加模型类

MVC约定是吧建立模型的类放在“Models”文件夹内。在“解决方案资源管理器”窗口中右击“Models”,从菜单中选择“添加——类”,命名为“GuestResponse.cs”。编辑该类内容如下图。

 

三:链接动作方法

在Index.cshtml视图中添加一个指向RSVP表单的链接,如下图。

Html.ActionLink是一个HTML辅助器方法(Helper Method),其作用时渲染一个超链接的HTML标记。MVC框架随带了一组内建的辅助器方法,它们可以方便地用来渲染HTML链接、文本输入框、单选框、甚至自定义控件等。这个ActionLink方法需要两个参数:第一个时链接的显示文本,第二个是当用户点击链接时将要执行的动作,ActionLink方法还有多个重载,将会在后面详细解释。开启调试,将会看到下图所示页面。

如果在浏览器中将鼠标指针一刀这个链接上,可以看到这个链接指向http://<服务器>/Home/RsvpForm。Html.ActionLink方法已经检测到了应用程序的URL路由配置,并得出/Home/RsvpForm是在一个叫做HomeController的控制器上调用RsvpForm动作的URL。

创建动作方法

如果点击这个链接,就会看到一个404错误提示,这是因为还没有创建与这个链接地址所对应的方法。把一个名为“RsvpForm“的动作方法添加到HomeController类,如下图

添加一个强类型视图

强类型视图意在渲染一个特定的域类型,而且,如果指定了想使用的类型,MVC将能够创建便于使用这个类型的便捷条件。

右击RsvpForm动作方法,在弹出菜单中选择“添加视图“,在添加视图对话框中,模板选择”Empty“,模型类选择GuestResponse,点击添加按钮,vs将创建一个名为” RsvpForm.cshtml“的视图文件。

如果所示,它有Rasor表达式@model。稍后会看到,这个@model是强类型视图的关键,也是为视图提供方便的关键。

四:建立表单

现在,强类型视图已经创建了,可以扩建RsvpForm.cshtml的内容,将其制作成编辑GuestResponse对象的HTML表单。如下图所示

对于GuestResponse模型类的每一个属性,可使用一个HTML辅助器方法来渲染一个适当的HTML的input控件。这些方法让用户能够用lambda表达式来选择与input元素有关的属性,如下所示。

@Html.TextBoxFor(x=>x.Phone)

这个HTML的TextBoxFor辅助器方法生成HTML的input元素,将其type参数设置为text,并把id和name标签属性值设置为Phone,Phone是所选域类的属性名,如下所示。

<input id="Phone" name="Phone" type="text" value="" />

可以发现,lambda表达式技术可以防止人们输错模型类型的属性名。

另一个方便的辅助器方法是Html.BeginForm,它生成一个回传给动作方法的HTML表单元素。由于没有给这个复制器方法传递任何参数,于是它假设用户是想回递给同样的URL。一个整洁的技巧就是把它封装在C#的using语句中,如下所示。

@using (Html.BeginForm()){

表单内容。。。

}

正常情况下,像这样运用using语句,会在对象超出范围时,确保对这个对象进行了清理。例如,这通常用于数据库连接,以确保查询完成后尽快关闭这个连接。

这个例子中并不是清理对象的目的,而是Html.BeginForm辅助器在它超出范围时关闭HTML的Form元素。

 

五:处理表单

此时还没有告诉MVC,将表单递交给服务器时要做什么。此刻,点击提交按钮只是清楚了表单中已经输入的值。这是因为,该表单会回递给Home控制器中的RsvpForm动作方法,它只告诉MVC再次渲染这个视图。

为了接收并处理表单所递交的数据,添加第二个RsvpForm动作方法,以形成如下作用。

一个方法用于响应HTTP的GET请求,另一个方法用于响应HTTP的POST请求。

默认情况下,用Html.BeginForm()渲染的表单是由浏览器作为一个POST请求递交的。

具体实现如下图所示。

此时新增了一个重载的RsvpForm动作方法,它带有一个GuestResponse参数,并运用了HTTPPOST注解属性。该注解属性告诉MVC,这个新方法将处理POST请求。注意,这里已经引入了PartyInvites.Models命名空间。

使用模型绑定

在新增的RsvpForm动作方法重载中,给定了GuestResponse类型参数,此处使用了模型绑定(Model Binding)特性。凭借此特性可以解析输入数据,并以键值对填充域模型类型的属性。

模型绑定时一个功能强大且可定制的特性,它消除了处理HTTP请求的繁琐,使开发者能够用C#对象进行工作,而不是处理Request.Form[]或Request.QuertyString[]的值。作为参数被传递给动作方法的GuestResponse对象自动地被填充了表单字段的数据。

渲染其他视图

RsvpForm动作方法的第二个重载也演示了如何才能告诉MVC去渲染一个对请求响应的特定视图。如下

return View("Thanks", guestResponse);

这个对View方法的调用告诉MVC,查找并渲染一个名为“Thanks“的视图,并把GuestResponse对象传递给这个视图。

新建一个名为Thanks的强类型视图,类型选择GuestResponse。编辑视图如下图所示

Razor的@model操作符指示了这个强类型试图的域模型类型。为了访问这个域对象中某个属性的值,要使用Model.PropertyName。例如,要获取Name属性的值,调用Model.Name。

开启调试,输入相关数据,点击提交,将会显示如下所示页面。

六:添加验证

为了防止用户输入无意义的值或直接提交一个空表单,需要对表单数据进行验证。在MVC应用程序中,验证典型地运用于域模型而不是用户界面。这意味着,在一个地方定义验证条件,会在运用模型类的任何地方生效。ASP.NET MVC支持验证规则声明,验证规则是以System.ComponentModel.DataAnnotations命名空间中的注解属性进行定义的。

编辑GuestResponse模型类文件,如下图。

之前对WillAttend属性使用了一个可空(nullable)的bool型。这样做是为了可以运用required验证注解属性。如果使用一个常规的bool型,通过模型绑定所接收的值只能是true或false,但不能判断用户是否已经选择一个值。一个可空的bool型有三个可能的值:true、false和null。如果用户尚未选择,系统会默认用null表示,这会使required注解属性报告一个验证错误。

我们可以在控制器类中使用ModelState.IsValid属性来检查是否有验证问题。如下图所示。

如果没有验证错误,便告诉MVC渲染Thanks视图,否则通过调用不带参数的View方法,重新渲染RsvpForm视图。

在有错误时仅显示表单并不十分有用,需要给用户提供一些指示,告诉他们有什么问题,以及为什么不能接受表单提交。通过在RsvpForm视图中使用Html.ValidaionSummary(验证摘要)辅助器方法可以完成这种工作,如下图所示。

如果没有错误,这个Html.ValidaionSummary方法会在表单中创建一个隐藏的列表条目占位符;否则,MVC会使这个占位符可见,并添加由验证注解属性所定义的错误消息,如下图所示。

直到所有验证约束都得到满足,用户才会看到Thanks视图。注意,在表单输入的数据是被保留的,并且,当验证摘要的视图被重新渲染时,这些数据会再次显示出来。这是通过使用模型绑定所得到的另一个好处。



博主声明

1、本博客主要为原创文章,转载请注明出处。

2、部分文章来自网络,已注明出处,如有侵权请与本人联系。

3、如果文章内容有误,或者您有其他更好的意见、建议请给我留言,我会及时处理!