前言

前面解说了怎样创建一个查询页面并给查询页面加入排序、搜索及分页功能。今天我们来讲讲怎样向这个列表加入数据。

解说的顺序将依照加入数据的步骤的时间顺序来进行,方便大家理清逻辑关系。

本节将涉及前面讲到的非常多知识点,并且还有非常多新知识点。帮助大家温故知新,融会贯通。

创建页面预览例如以下:

新建链接

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

<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):新建数据页面的更多相关文章

  1. ASP.Net MVC开发基础学习笔记:一、走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  2. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  3. ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法

    一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...

  4. ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习

    一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...

  5. ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  6. ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  7. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  8. ASP.Net MVC开发基础学习笔记(4):校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  9. ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

    一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...

  10. ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法

    一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...

随机推荐

  1. [转]mysql Access denied for user 'root'@'localhost' 问题的解决方法

    解决方案如下: # /etc/init.d/mysql stop # mysqld_safe --user=mysql --skip-grant-tables --skip-networking &a ...

  2. Leetcode26--->Remove Duplicates from Sorted Array(从排序数组中移除相同的元素)

    题目: 给定一个排序数组,移除重复出现的元素,保证每个元素最终在数组中只出现一次.返回新数组的长度length; 要求:不能分配额外的一个数组使用,必须使用原地排序的思想,且空间复杂度为O(1) 举例 ...

  3. 对python的想法

    作为计算机专业的学生,在编程语言之余,我认为掌握一门脚本语言是很必要的.尤其是现在在数据分析,AI,机器学习等各个方面都大放异彩的python.相比于之前接触过的Java,C,C++乃至于php等语言 ...

  4. 思路清奇:通过 JavaScript 获取移动设备的型号

    我们一般在浏览器里识别用户的访问设备都是通过 User Agent 这个字段来获取的,但是通过它我们只能获取一个大概的信息,比如你用的是 Mac 还是 Windows,用的是 iPhone 还是 iP ...

  5. AtCoder Regular Contest 091

    数学场,做到怀疑人生系列 C - Flip,Flip, and Flip...... Time limit : 2sec / Memory limit : 256MB Score : 300 poin ...

  6. Welcome-to-Swift-07闭包(Closures)

    闭包是自包含的函数代码块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似. 闭包可 ...

  7. 用js判断浏览器类型及设备

    <!DOCTYPE html> <html> <head> <title>JS判断是什么设备是什么浏览器</title> <meta ...

  8. 刷题总结——分糖(ssoj 容斥原理+逆元+快速幂+组合数求插板)

    题目: 题目描述 有 N 个(相同的)糖果,M 个(不同的)小朋友.M 和 N 满足:1≤M≤N≤100000(105).要求:1.每个小朋友都至少有一个糖果.2.不存在正整数 X(X>=2), ...

  9. iOS-CALayer && CAAnimation

    一.CALayer 1.CALayer CALayer属于QuartzCore.framework框架,从Xcode5起我们不必要手动导入这个库. CALayer我们可以简单理解为一个层.当我们绘制的 ...

  10. UPC 2223: A-Number and B-Number(数位DP+二分)

    积累点: 1: (l&r)+((l^r)>>) == (l+r)/2 2: 注意判断现在是否有限制.当枚举下一个量时,是(isQuery && j==end),不要 ...