ASP.Net MVC开发基础学习笔记(8):新建数据页面
前言
前面解说了怎样创建一个查询页面并给查询页面加入排序、搜索及分页功能。今天我们来讲讲怎样向这个列表加入数据。
解说的顺序将依照加入数据的步骤的时间顺序来进行,方便大家理清逻辑关系。
本节将涉及前面讲到的非常多知识点,并且还有非常多新知识点。帮助大家温故知新,融会贯通。
创建页面预览例如以下:

新建链接
首先在之前创建好的查询页面上加入一个可以跳转到创建页面的链接。将这个链接加入到标题和搜索栏之间。代码例如以下:
<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视图,写入例如以下代码:
@model SlarkInc.Models.Worker
@{
ViewBag.Title = "Add New Worker";
}
<h2>Add New Worker</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Sex, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(model => model.Sex)
@Html.ValidationMessageFor(model => model.Sex)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Rating, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.Submit("Submit")
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
View的第1行代码例如以下所看到的,引入了Models目录里的Worker类。
@model SlarkInc.Models.Worker
为了更好的进行数据操作,Worker类做了修改,修改之后的代码例如以下:
隐藏代码using System.ComponentModel.DataAnnotations;
namespace SlarkInc.Models
{
public enum Sex
{
Male, Female
}
public class Worker
{
public int ID { get; set; }
[Display(Name = "Last Name")]
[DataType(DataType.Text)]
[Required]
public string LastName { get; set; }
[Display(Name = "First Name")]
[DataType(DataType.Text)]
[Required]
public string FirstName { get; set; }
[Required]
public Sex Sex { get; set; }
public double?
Rating { get; set; }
}
}
代码中第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类型的数据在页面上下面拉菜单的形式显示出来供人编辑。
只是这个函数可不是那么easy用,首先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。代码例如以下:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "FirstName, LastName, Sex, Rating")] Worker worker)
{
try
{
if (ModelState.IsValid)
{
db.Workers.Add(worker);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
ModelState.AddModelError("unableToSave","Unable to save changes.Try again, and if the problem persists see your system administrator.");
}
return View(worker);
}
注意。之前我们已经写了一个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"链接。

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

填入正确信息例如以下:

点击Submitbutton,成功加入数据后的结果例如以下:

结尾
最终又完毕了一篇,再接再厉!
ASP.Net MVC开发基础学习笔记(8):新建数据页面的更多相关文章
- ASP.Net MVC开发基础学习笔记:一、走向MVC模式
一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...
- ASP.Net MVC开发基础学习笔记(1):走向MVC模式
一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...
- ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法
一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...
- ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习
一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...
- ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器
一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...
- ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- ASP.Net MVC开发基础学习笔记(4):校验、AJAX与过滤器
一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...
- ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习
一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...
- ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法
一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...
随机推荐
- 第1章jquery选择器
一.jquery等价于$ jquery选择器继承了css选择器的风格. $("#ID")代替了document.getElementById()函数,即通过id获取元素. $(&q ...
- Linux免密远程登陆
上一节讲到伪分布式部署,启动后需要输入4次密码,停止服务后也要输入4次密码.本节记录免密登陆原理和实践 假设有2台服务器(A和B)(这是配置原理) 1)A需要远程登录B服务器,那么A就要创建密钥对(私 ...
- javascript学习笔记-数据类型
一 数据类型 基本类型:undefined,null,boolean,number,string 保存在栈内存中 占用空间固定 变量直接从栈内存中存取的是该值 引用类型: ...
- poj1236 Tarjan算法模板 详解
思想: 做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最早的节点的开始时间.初始时dfn ...
- 【转】[译]深入理解JVM
http://www.cnblogs.com/enjiex/p/5079338.html 深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/un ...
- iOS--自定义相册---对象数组按照时间戳排序
将对象按照时间戳排序,这里典型的一个例子是登录账户的排序:本地客户端可能保存了多个账户信息,在登录窗口用户可以选择已经登陆过的账户直接登录,现在的需求是要时刻让最近登陆过的账户排在前面,对于每个账户, ...
- kb-07线段树-05-区间整体修改查询;(水)
/* */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; s ...
- LSU——1116 Necklace(尺取)
1116 Necklace 通过率:5/23 难度系数:0时间限制:1000ms 内存限制:32000KB java 两倍. 介绍 Little King has a beautiful pearl ...
- poj3728The merchant
The merchant Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 4800 Accepted: 1666 Desc ...
- Java面试题之final、finally和finalize的区别
final: final是一个修饰符,可以修饰变量.方法和类,如果final修饰变量,意味着变量的值在初始化后不能被改变: 防止编译器把final域重排序到构造函数外:(面试的时候估计答出这个估计会加 ...