(12) MVC5 EF6 Bootstrap3
MVC5 + EF6 + Bootstrap3 (12) 新建数据
上一节:MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页
源码下载:点我下载
目录
前言
前面讲解了如何创建一个查询页面并给查询页面添加排序、搜索及分页功能。今天我们来讲讲如何向这个列表添加数据。
讲解的顺序将按照添加数据的步骤的时间顺序来进行,方便大家理清逻辑关系。本节将涉及前面讲到的很多知识点,而且还有很多新知识点。帮助大家温故知新,融会贯通。
创建页面预览如下:

新建链接
首先在之前创建好的查询页面上添加一个能够跳转到创建页面的链接,将这个链接添加到标题和搜索栏之间。代码如下:

<h2>Students</h2> <p>
@Html.ActionLink("Create New", "Create")
</p> @using (Html.BeginForm("Index","Student", FormMethod.Get))
{
<p>
Find by name:@Html.TextBox("SearchString",ViewBag.CurrentFilter as string)
<input type="submit" value="Search"/>
</p>
}

上面代码中黄色部分就是添加的链接,这个ActionLink生成的HTML代码如下:
<a href="/Company/Create">Add New Worker</a>
可以看到这个链接访问的是CompanyController下的Create Action。下面来创建这个Action。
新建页面Action
打开文件~\Controllers\CompanyController.cs。在这个Controller中添加一个Create Action,如下所示:
public ViewResult Create()
{
return View();
}
这么简单?对就是这样,创建数据的页面所有信息都需要用户去填,自然不需要传递数据,也就没有什么操作。
这个Action调用了它对应的View,那么我们就来创建这个View。
新建页面View
在~\Views\Company\文件夹下创建Create.cshtml视图,写入如下代码:

1 @model SlarkInc.Models.Worker
2 @{
3 ViewBag.Title = "Add New Worker";
4 }
5 <h2>Add New Worker</h2>
6 @using (Html.BeginForm())
7 {
8 @Html.AntiForgeryToken()
9 <div class="form-horizontal">
10 <hr />
11 @Html.ValidationSummary(true)
12 <div class="form-group">
13 @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
14 <div class="col-md-10">
15 @Html.EditorFor(model => model.FirstName)
16 @Html.ValidationMessageFor(model => model.FirstName)
17 </div>
18 </div>
19 <div class="form-group">
20 @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })
21 <div class="col-md-10">
22 @Html.EditorFor(model => model.LastName)
23 @Html.ValidationMessageFor(model => model.LastName)
24 </div>
25 </div>
26 <div class="form-group">
27 @Html.LabelFor(model => model.Sex, new { @class = "control-label col-md-2" })
28 <div class="col-md-10">
29 @Html.EnumDropDownListFor(model => model.Sex)
30 @Html.ValidationMessageFor(model => model.Sex)
31 </div>
32 </div>
33 <div class="form-group">
34 @Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" })
35 <div class="col-md-10">
36 @Html.EditorFor(model => model.Rating)
37 @Html.ValidationMessageFor(model => model.Rating)
38 </div>
39 </div>
40 <div class="form-group">
41 <div class="col-md-offset-2 col-md-10">
42 @Html.Submit("Submit")
43 </div>
44 </div>
45 </div>
46 }
47 <div>
48 @Html.ActionLink("Back to List", "Index")
49 </div>

View的第1行代码如下所示,引入了Models文件夹里的Worker类。
@model SlarkInc.Models.Worker
为了更好的进行数据操作,Worker类做了改动,改动之后的代码如下:

1 using System.ComponentModel.DataAnnotations;
2 namespace SlarkInc.Models
3 {
4 public enum Sex
5 {
6 Male, Female
7 }
8 public class Worker
9 {
10 public int ID { get; set; }
11 [Display(Name = "Last Name")]
12 [DataType(DataType.Text)]
13 [Required]
14 public string LastName { get; set; }
15 [Display(Name = "First Name")]
16 [DataType(DataType.Text)]
17 [Required]
18 public string FirstName { get; set; }
19 [Required]
20 public Sex Sex { get; set; }
21 public double? Rating { get; set; }
22 }
23 }

代码中第1行引入了DataAnnotations类库,这样我们就可以在Worker类中添加元数据来在View中更好的操作数据。关于这部分内容可以点这里进一步了解。
看View的第13行代码:
@Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
这里的LabelFor函数用来显示这个数据对应的名称,它会去找Worker类的FirstName对应的数据名称,也就是Model里的第15行:
[Display(Name = "First Name")]
然后用Html把它显示出来,如下:
<label class="control-label col-md-2" for="FirstName">First Name</label>
View中的第15行:
@Html.EditorFor(model => model.FirstName)
会根据Model中的第16行:
[DataType(DataType.Text)]
来决定用哪种input元素来编辑数据,既然是Text类型的,那就用type="text"的input,如下所示:
<input class="text-box single-line" data-val="true" data-val-required="First Name 字段是必需的。" id="FirstName" name="FirstName" type="text" value="" />
那上面的代码中 "data-val-required="First Name 字段是必需的。"" 这一段是哪来的呢?
这是EditorFor函数读取到Model中的第17行:
[Required]
这一行表示这个数据是必填项,如果不填则会显示信息"First Name 字段是必需的。"。
在View中的第29行用到函数Html.EnumDropDownListFor,如下所示:
@Html.EnumDropDownListFor(model => model.Sex)
这个函数可以把Enum类型的数据在页面上以下拉菜单的形式显示出来供人编辑。
不过这个函数可不是那么容易用,首先Visual Studio的版本必须是2013或者以上的,项目必须用的是MVC5,然后在菜单中选择工具->库程序包管理器-> 管理解决方案的NuGet程序包。如下所示选择联机,在左上角搜索MVC然后安装最新的MVC 5.2.2版。

更新好之后,这个函数就可以正常使用了。它会根据Sex这个Enum变量来生成下拉菜单。这个Enum的定义如下:
public enum Sex
{
Male, Female
}
那么它生成的下拉菜单代码如下:
<select data-val="true" data-val-required="Sex 字段是必需的。" id="Sex" name="Sex">
<option selected="selected" value="0">Male</option>
<option value="1">Female</option>
</select>
View的第16行代码:
@Html.ValidationMessageFor(model => model.FirstName)
其中ValidationMessageFor函数用来验证数据的有效性。它根据在Model中这个属性的类型来验证输入的值是否符合要求。比如Rating这个属性是Double类型的,那么在输入数据时,如果数据不是数字则会有相应提示,并且不能提交。
View的第6、7、46行是如下所示的不带参数的Form函数结构:
@using (Html.BeginForm()){}
这样的结构如果不带任何参数,则Form会以Post方法提交给本页面对应的Controller和Action,因此其生成的HTML代码就是如下形式:
<form action="/Company/Create" method="post"></form>
在View中使用了Bootstrap的横向表单布局其结构如下:

<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-2" for=""></label>
<div class="col-md-10">
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for=""></label>
<div class="col-md-10">
</div>
</div>
</div>

显示出来的效果如下所示:

每一行对应一个属性,左边是属性名,右边是属性对应的编辑框。属性名的col-md-2表示其占Form总宽度的2/12,col-md-10表示其占Form总宽度的10/12。这用到了Bootstrop的栅格系统。栅格系统详细介绍请点这里。
View第8行@Html.AntiForgeryToken()函数的作用是抵御网页跨站请求伪造漏洞(CSRF Cross-site request forgery)。这个漏洞可以盗用登录用户身份发送恶意请求。比如一个用户登录了网上银行,然后访问攻击者的网站,网站就会通过登录用户发出请求来获取银行信息。
View第11行使用Html.ValidationSummary(true)。表示只输出Model级的验证错误信息。其具体用法会在后面章节中详细介绍。
上面这几段对Create.cshtml文件中具有代表性的技术知识点做了详细说明,其他行不再赘述,有问题请留言。
添加数据Action
从上面代码可以看出,Create.cshtml页面会把数据提交给当前页面对应的Controller和Action,因此我们就在CompanyController下写处理提交的数据的Action。代码如下:

1 [HttpPost]
2 [ValidateAntiForgeryToken]
3 public ActionResult Create([Bind(Include = "FirstName, LastName, Sex, Rating")] Worker worker)
4 {
5 try
6 {
7 if (ModelState.IsValid)
8 {
9 db.Workers.Add(worker);
10 db.SaveChanges();
11 return RedirectToAction("Index");
12 }
13 }
14 catch (DataException /* dex */)
15 {
16 ModelState.AddModelError("unableToSave","Unable to save changes.Try again, and if the problem persists see your system administrator.");
17 }
18 return View(worker);
19 }

注意,之前我们已经写了一个Create Action用来进入添加页面,这里的Create不是修改前面的Create。而是新建了一个Action。
第1行在这个Action前加[HttpPost]表示只有以Post方法请求Create Action的时候才会调用这个Action。
第2行ValidateAntiForgeryToken依然是为了防止跨站请求伪造攻击而写的代码。
第3行Action的参数是以worker实例传递的。也就是说Create.cshtml提交的4个值被赋值给work然后把worker传递给Create作为参数。而这个参数前面的[Bind(Include = "FirstName, LastName, Sex, Rating")]是为了防止过多提交(overposting)攻击的。从Create.cshtml的代码可以知道,这个页面只会提交4个值。而黑客可以有办法通过这个页面提交更多的值给当前Action,而这些多出来的值也会存在worker实例中被添加到数据库,这无疑是危险的。因此[Bind(Include = "")]就限定了不管你提交多少值,我这个Action里只接受"FirstName, LastName, Sex, Rating"这4个值。保证了页面的安全性。
第7行ModelState.IsValid表示提交的数据是否有效。比如对于一个类型为数字的属性必须提交一个数字才算是有效。如果提交的数据有效则保存数据并且将页面跳转回Index.cshtml。
第16行ModelState.AddModelError()函数可以给Model添加一条错误信息,函数的第一个参数是key,用于查找这个错误信息,第二个参数是错误信息的具体内容。这个错误信息可以在View中通过Html.ValidationMessage("unableToSave")来访问到。
查看结果
点击下图的"Add New Worker"链接。

放空必填项或者输入不合法数据出现提示信息如下:

填入正确信息如下:

点击Submit按钮,成功添加数据后的结果如下:

结尾
终于又完成了一篇,再接再厉!
喜欢就推荐下吧!
本节主要参考:Implementing Basic CRUD Functionality with the Entity Framework in ASP.NET MVC Application
上一节:MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页
作者:Slark.NET
出处:http://www.cnblogs.com/slark/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。
(12) MVC5 EF6 Bootstrap3的更多相关文章
- MVC5 + EF6 + Bootstrap3 (12) 新建数据
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-create.html 系列教程:MVC5 + EF6 + ...
- MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页
系列教程:MVC5 + EF6 + Bootstrap3 上一节:MVC5 + EF6 + Bootstrap3 (10) 数据查询页面 源码下载:点我下载 我工作的源码:http://www.jin ...
- MVC5 + EF6 + Bootstrap3 (14) 分部视图PartialView
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-partialview.html 系列教程:MVC5 + E ...
- MVC5 + EF6 + Bootstrap3 (13) 查看详情、编辑数据、删除数据
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-rud.html 系列教程:MVC5 + EF6 + Boo ...
- MVC5 + EF6 + Bootstrap3 (10) 数据查询页面
文章来源:Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-search-page.html 系列教程:MVC ...
- MVC5 + EF6 + Bootstrap3 (7) Bootstrap的栅格系统
文章来源: Slark.NET-博客园http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-grid.html 上一节:ASP.NET MVC ...
- MVC5 + EF6 + Bootstrap3系列教程
本系列教程以ASP.NET MVC5为核心框架,使用Entity Framewok6访问数据,并使用Bootstrap3作为前端UI框架.帮助大家开发出一套高效.美观.稳定.实用的软件系统. MVC5 ...
- MVC5 + EF6 + Bootstrap3 (16) 客户端验证
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-client-side-validation.html 系列 ...
- MVC5 + EF6 + Bootstrap3 (15) 应用ModelState和Data Annotation做服务器端数据验证
Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-server-side-validation.html 系列 ...
随机推荐
- Android4.0 Design之UI设计缺陷1
我想成为Android卓越发展project联赛,不知道Android它如何设计规则,Android4.0谷歌公司的问世后Android一系列的设计原则,程序猿规范,不要盲目模仿IOS它的设计,由于A ...
- R语言做文本挖掘 Part4文本分类
Part4文本分类 Part3文本聚类提到过.与聚类分类的简单差异. 那么,我们需要理清训练集的分类,有明白分类的文本:測试集,能够就用训练集来替代.预測集,就是未分类的文本.是分类方法最后的应用实现 ...
- 我的第一次windows规划
#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //WinMain功能被分配一 ...
- 百度地图 iOS SDK - 坐标转换方法
百度地图 Android SDK 要么 iOS SDK 或各种 API 工具产品,我们使用百度自己的加密坐标系. 员在使用过程中,位置点都是通过 GPS 或者其它途径获取的.所以与百度地图所使用的坐标 ...
- Visual Studio Team Services使用教程--默认团队权限说明
- GDI+学习笔记(六)渐变画笔
刷,顾名思义,它是一样的刷.提请设备,还记得常唱歌曲,"我是一个画家.." 好吧.跑题了. 本系列博客希望尽可能简单的描写叙述每项功能,而不希望把每一个參数都介绍的详具体细,假设须 ...
- 全自动Web后门扫描(转)
阅读目录 工具介绍 使用方法 工具介绍 这是一款全自动Web后门查杀工具,基于Python开发 某些较新的后门可能会查杀失败 规则列表来自seay博客 回到顶部 使用方法 1.按恶意代码查杀: pyt ...
- android开源应用(主要是博客上带有分析的)收集 【持续更新】
2014.5.24更新: (android高仿系列)今日头条 http://blog.csdn.net/vipzjyno1/article/details/26514543 CSDN Andro ...
- wikioi 1034 家 实时动态的网络流量(费用流)
因为随着时间的推移.网络侧变得,因此,常见的网络流量也解决不了这个问题,.如果T毕竟运输时间. 为此.我们可以基于时间分割点,所有的点将被分割为T点. 对于每一个点,下一次甚至一个容量为本人INF边缘 ...
- 浅谈Hybrid技术的设计与实现(转)
前言 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发效率的要求,这个时候使用IOS&Andriod开发一个APP似乎成本有点过高了,而H5的低成本.高效率.跨平台等特性 ...