经过之前n多的铺垫

我们已经大概了解了这个姓m名vc的家伙了

那么今天我们就来体验一把

怎么体验呢?

就来做一个小例子吧~

mvc增删改查的例子

数据库还是之前我们的老朋友

关系图:

表中的数据已填好

T_Users

将就着用着吧,哈哈

现在要求对T_Users表进行增删改查

开搞~

回到之前新建的mvc项目

在Controllers文件夹下新建一个名为Home的空控制器

当浏览器请求Home下面的Index方法的时候返回什么?

当然是主页面啦

这里我们的主页面就是显示T_Users数据列表

代码如下:

//首先我们需要一个EF上下文实例,这是必须的
private Entities dbEntities = new Entities(); //通过数据上下文将T_Users的数据查询出来并展示
public ActionResult Index()
{
//将T_Users表的数据都取出来
var users = dbEntities.T_Users.Where(u => true).ToList();
//并交给ViewData.Model
ViewData.Model = users;
return View();
}

这个ViewData.Model是个啥飞机?

别急~

我们先接着往下走

在Index方面上右键->添加视图

注意先不要使用母版页哦~

Index.cshtml代码如下:

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div> </div>
</body>
</html>

很正规的一个html页面

等等

头部的Layout=null又是个啥飞机?

Layout就是一个布局的意思

我们可以看到Layout=null是被包在一个@{ }里面的

前面我们说过

这是一种razor视图引擎的语法,那么久很明显这是一行C#代码

其实它的作用就是将本页面的布局页(也可以说是母版页)清空

因为我们新建视图的时候没有选择嘛~

如果你选择了使用母版页,Layout就会指向一个母版页文件

那么我们继续往下走~

在这个html页中

用一个table标签来展示T_Users的数据

<table id="tbList">
<tr>
<td>Id
</td>
<td>UserName
</td>
<td colspan="2">操作
</td>
</tr>
@foreach (var u in Model)
{
<tr>
<td>@u.Id
</td>
<td>@u.UserName
</td>
<td>
<a href="/Home/Modify/@u.Id">Modify</a>
</td>
<td>
<a href="/Home/Delete/@u.Id">Delete</a>
</td>
</tr>
}
</table>

这段代码没啥难度吧~

但是foreach循环的那个Model是哪里来的,为什么它会有我们需要的数据?

回头想想

之前我们是不是把users都交给了ViewData的一个Model属性?

没错,ViewData的Model属性在前台可以直接通过Model访问

在后台,你甚至可以这样做:

public ActionResult Index()
{
//将T_Users表的数据都取出来
var users = dbEntities.T_Users.Where(u => true).ToList();
//并交给ViewData.Model
//ViewData.Model = users;
return View(users);//直接将users当做参数传入View,可以直接在前台用过Model属性来获得数据
}

这两种方式效果是一样的

不信你试试~我会骗你?

试试又不用钱~

那么这时可能会有一个问题

如果我要传两个数据给前台怎么办?

都用Model吗

那不就覆盖了?

这时候ViewBag就要登场了

我们在将代码改成这个样子

//通过数据上下文将T_Users的数据查询出来
public ActionResult Index()
{
//将T_Users表的数据都取出来
var users = dbEntities.T_Users.Where(u => true).ToList();
//并交给ViewData.Model
//ViewData.Model = users; //通过ViewBag传递数据给前台
ViewBag.Users = users;
return View();
}

注意!

ViewBag后面的Users属性并不是固定的

也就是说

你可以根据你的爱好,随便你怎么取名ViewBag的属性,然后只要将数据交给它就ok!

爽不爽?~

当然,在前台现在就不能用Model属性了

@foreach (var u in ViewBag.Users)
{
<tr>
<td>@u.Id
</td>
<td>@u.UserName
</td>
<td>
<a href="/Home/Modify/@u.Id">Modify</a>
</td>
<td>
<a href="/Home/Delete/@u.Id">Delete</a>
</td>
</tr>
}

在后台,你用ViewBag点了什么属性赋值了数据,在前台同样通过这个属性取数据

这样一来我们就可以通过ViewBag随意的传递n多数据了

很方便吧~

现在先来瞧瞧网站运行起来的样子(在mvc项目上右键浏览器中查看)

数据是出来了

但是..

这也太丑了吧

加点样式~

<head>
<meta name="viewport" content="width=device-width" />
<style type="text/css">
#tbList
{
border: 1px solid #0094ff;
width: 400px;
margin: 20px auto;
border-collapse: collapse;
} #tbList td, #tbList th
{
border: 1px solid #0094ff;
padding: 20px;
}
</style>
<title>Index</title>
</head>

保存,刷新

是不是好看了一点= =

将就着用吧~

好了,查询搞定

那接下来就先做新增

<tr>
<td>Id
</td>
<td>UserName
</td>
<td>操作
</td>
<td>
<a href="/Home/Create">新增</a>
</td>
</tr>

原谅我随便找了一个地方插进去一个超链接....

在后台的Home控制器中就要添加一个对应的Create方法

//返回新增的页面
public ActionResult Create()
{
return View();
}

还是右键添加视图

显示一个新增的页面

<body>
<form action="/Home/Create" method="POST">
<input type="text" name="txtUserName"/>
<input type="submit" value="添加"/>
</form>
</body>

看到这个form的action指向Home的Create方法有同学就会有疑问了

前面展示新增页面也是指向Create方法,现在提交数据表单也指向Create方法

那怎么搞?

上代码:

 //用HttpPost来标记本方法只有post请求的时候才会被执行
[HttpPost]
public ActionResult Create(T_Users user)
{
string userName = Request.Form["txtUserName"];
user = new T_Users() {UserName = userName};
dbEntities.T_Users.Add(user);
dbEntities.SaveChanges();
//重定向到Index方法,作用相当于webform的Response.Redirect
return Redirect("/Home/Index");
}

现在明白了吧~

我们只需要在方法之前加个[HttpPost]标记就ok

反之[HttpGet]当然是只有get请求才会被执行的咯~

好的

代码完成,重新生成,然后刷新页面

点击新增超链接,出现新增页面

是不是有点简单...

随便啦~

点击添加按钮提交表单

成功添加~

接下来在后台在添加一个Modify修改方法

//显示修改页面
public ActionResult Modify(int id)
{
//根据id取出数据库中对应的数据
var user = dbEntities.T_Users.Where(u => u.Id == id).FirstOrDefault();
return View(user);
}

添加视图,html代码:

<body>
<form action="/Home/Modify/@Model.Id" method="POST">
<input type="text" name="UserName" value="@Model.UserName"/>
<input type="submit" value="保存修改"/>
</form>
</body>

这里需要注意一个问题,文本框标签的name属性的取值最好为对应实体的属性名

什么意思呢?

就那上面的例子来说

T_Users有一个UserName属性,那么这个文本框是针对该属性设置的,所以name="UserName"

如果有一个文本框是针对Id属性的,那么这个文本框的name最好等于Id

为什么要这么做?

因为如果name=具体的实体属性的话

表单提交到后台的时候Modify方法用一个T_Users参数接收,系统会将表单中 name值 和 T_Users属性同名 的标签 值 自动填充到 T_Users对象对应的属性中

如:

//接收post请求的修改方法
[HttpPost]
public ActionResult Modify(T_Users user)//如果表单中的标签 name值 等于 user的属性名 系统会自动将表单中的值填充到此user实体中
{
//附加实体到数据上下文,并设置属性的修改状态
var entry = dbEntities.Entry(user);
entry.State = EntityState.Unchanged;
entry.Property("UserName").IsModified = true;
dbEntities.SaveChanges();
return Redirect("/Home/Index");
}

这叫做模型绑定

当然你也可以不按照这个规定来

只是需要另外接收表单的参数而已~

这时候我们重新生成并刷新页面

点击Modify超链接

这时有可能会出现一个错误,如下图:

别着急,不要一看到异常就慌~

这是一个mvc实体验证的设置

我们为Home控制器类添加一个构造函数,并在构造函数中关闭实体验证即可

public HomeController()
{
//关闭实体验证
dbEntities.Configuration.ValidateOnSaveEnabled = false;
}

现在在来重新生成并刷新~

点击保存

成功修改~

最后的删除方法就简单了

//删除方法
public ActionResult Delete(int id)
{
T_Users user = new T_Users() {Id = id};
dbEntities.T_Users.Attach(user);
dbEntities.T_Users.Remove(user);
dbEntities.SaveChanges();
return Redirect("/Home/Index");
}

这里直接点击删除超链接就执行删除方法

如果有需要你也可以添加一个视图先展示一下要删除的数据,然后在点击确定删除~

最后提一个关于生成下拉框的小小的问题

如果在展示修改页面的时候要求将该user实体关联的T_Products实体用下拉框显示出来

T_Products表如下:

第一种做法:

在后台取出相应的T_Products数据

//显示修改页面
public ActionResult Modify(int id)
{
//根据id取出数据库中对应的数据
var user = dbEntities.T_Users.Where(u => u.Id == id).FirstOrDefault();
//查询出T_Products表中属于该对象的数据
var products = dbEntities.T_Products.Where(p => p.Uid == id).ToList();
//并将其传入ViewBag
ViewBag.Products = products;
return View(user);
}

前台展示:

<body>
<form action="/Home/Modify/@Model.Id" method="POST">
<input type="text" name="UserName" value="@Model.UserName"/>
<select name="T_Products">
@foreach (var p in ViewBag.Products)
{
<option value="@p.Id">@p.ProName</option>
}
</select>
<input type="submit" value="保存修改"/>
</form>
</body>

页面效果:

这是正常使用htmlselect标签的方法

但是在mvc中还提供Lee另外一种方式

第二种做法:

先来看前台代码

<body>
<form action="/Home/Modify/@Model.Id" method="POST">
<input type="text" name="UserName" value="@Model.UserName"/>
@*第一种做法:
<select name="T_Products">
@foreach (var p in ViewBag.Products)
{
<option value="@p.Id">@p.ProName</option>
}
</select>*@ @*第二种做法,使用HtmlHelper类*@
@Html.DropDownList("T_Products",ViewBag.Products as IEnumerable<SelectListItem>)
<input type="submit" value="保存修改"/>
</form>
</body>

HtmlHelper类时mvc内置的一个帮助程序员快速生成html代码的类,可以简写成Html

例如本例中的Html.DropDownList最终就是生成一个下拉框

其第一个参数是下拉框的name属性,第二个参数是一个IEnumerable<SelectListItem>类型的集合(就是要展示的数据,但是要先转成IEnumerable<SelectListItem>才行)

所以在后台

我们先拿到要展示的数据

//显示修改页面
public ActionResult Modify(int id)
{
//根据id取出数据库中对应的数据
var user = dbEntities.T_Users.Where(u => u.Id == id).FirstOrDefault(); //第一种做法
//查询出T_Products表中属于该对象的数据
//var products = dbEntities.T_Products.Where(p => p.Uid == id).ToList();
//并将其传入ViewBag
//ViewBag.Products = products; //第二种做法
List<SelectListItem> products =
dbEntities.T_Products.Where(p => p.Uid == id)
.ToList()//查询出T_Products集合
.Select(p => new SelectListItem { Text = p.ProName, Value = p.Id.ToString() })//将实体集合转换成SelectListItem类型
.ToList();//在转换成List<SelectListItem>集合
//传入ViewBag
ViewBag.Products = products;
return View(user);
}

重新生成并刷新

两种方式的效果是一样的

第二种是mvc特有的

现在可能使用起来很不习惯

但是HtmlHelper是mvc开发经常使用的类

以后我们会在详细说明

好了,现在一套mvc的基本增删改查已经完成

多多少少还是有点收获的是吧~

ASP.NET MVC学习---(五)MVC初体验的更多相关文章

  1. 第三次随笔--安装虚拟机及学习linux系统初体验

    第三次随笔--安装虚拟机及学习linux系统初体验 ·学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 首先按照老师的提示步骤进行VirtualBox虚拟 ...

  2. 算法学习:并行化初体验_JAVA实现并行化归并算法

    这个系列包括算法导论学习过程的记录. 最初学习归并算法,对不会使其具体跑在不同的核上报有深深地怨念,刚好算倒重温了这个算法,闲来无事,利用java的thread来体验一下并行归并算法.理论上开的thr ...

  3. Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用[z]

    前言 早在去年就简单的使用了一下Spring Boot,当时就被其便捷的功能所震惊.但是那是也没有深入的研究,随着其在业界被应用的越来越广泛,因此决定好好地深入学习一下,将自己的学习心得在此记录,本文 ...

  4. Yaf学习(二)----Yaf初体验

    1.hello world 1.1 用yaf输出hello world 1.首先配置host,nginx 2.host不用多说,指向虚拟机IP即可 1.2 重点说一下nginx (只说server块) ...

  5. MVC学习五:Razor布局页面 _ViewStart.cshtml

    如图: _ViewStart.cshtml就是MVC中的布局页面/模板页面. 用户访问流程图: 原理:先去执行Views文件夹下[_ViewStart.cshtml]页面,然后同级目录文件夹(上图中的 ...

  6. MVC学习笔记---MVC生命周期及管道

    ASP.NET和ASP.NET MVC的HttpApplication请求处理管道有共同的部分和不同之处,本系列将体验ASP.NET MVC请求处理管道生命周期的19个关键环节. ①以IIS6.0为例 ...

  7. MVC学习笔记---MVC的处理管线

    漫步ASP.NET MVC的处理管线   ASP.NET MVC从诞生到现在已经好几个年头了,这个框架提供一种全新的开发模式,更符合web开发本质.你可以很好的使用以及个性化和扩展这个框架,但这需要你 ...

  8. Visual Studio Code 学习.net core初体验

    一,安装 最近在用 Visual Studio Code 学习.net core ,记录下学习的过程,首先去官网下载最新的.net core2.1安装包,有windows 和mac,根据自己的开发环境 ...

  9. MVC学习笔记---MVC生命周期

    Asp.net应用程序管道处理用户请求时特别强调"时机",对Asp.net生命周期的了解多少直接影响我们写页面和控件的效率.因此在2007年和2008年我在这个话题上各写了一篇文章 ...

  10. MVC学习笔记---MVC导出excel(数据量大,非常耗时的,异步导出)

    要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...

随机推荐

  1. BZOJ1800 [Ahoi2009]fly 飞行棋 【枚举】

    题目 给出圆周上的若干个点,已知点与点之间的弧长,其值均为正整数,并依圆周顺序排列. 请找出这些点中有没有可以围成矩形的,并希望在最短时间内找出所有不重复矩形. 输入格式 第一行为正整数N,表示点的个 ...

  2. hibernate中类状态转换

  3. java的struts2整理

    readbook:struts2 先说一下struts1:    struts1使用model II 模式开发,即jsp+java bean+servlet    再说它的缺陷:    1.表现层支持 ...

  4. 汕头市队赛 SRM10 T1模拟只会猜题意

    模拟只会猜题意 SRM 10 描述 有一本n个单词的词典,求按下列方法能造出的不相同的词汇数目.  1.词典中的单词是一个词. 2.能分为两部分的,其中前一部分是一个词典词或者其非空前缀,后一部分是一 ...

  5. Scenes in Cocos2D

    https://www.makeschool.com/docs/?source=mgwu#!/cocos2d/1.0/scenes Scenes in Cocos2D In Cocos2D you h ...

  6. 设置JPA的Query返回Map对象

    说明正常执行jpa查询的时候需要传一个对应实体进行映射返回的数据,这样有时候如果一个sql是复合sql关联很多表,就需要新建实体有点麻烦,通过下面方式就能将返回结果映射成map.这样就能随意获取返回结 ...

  7. linux dev设备

    /dev目录的文件都是设备,我们可以像操作文件一样操作设备.但是究竟什么才是设备文件哪?作为程序员不能用代码敲出来的概念我们都是不喜欢的,所以本文用shell来操作体验什么才是/dev文件. 我们执行 ...

  8. git回溯到指定版本

    git回溯到指定版本 git log命令查看仓库日志 然后使用git checkout 命令 例如回溯到上图中的版本 git checkout 12db5d6fd138922a8aaf2214c84c ...

  9. git从远程仓库中更新代码到本地仓库

    git从远程仓库中更新代码到本地仓库 有时候在使用git pull的时候,会莫名才报错.查了很多资料,尝试过git的很多命令.包括git fetch命令,都会报同样的错.最后终于发现了一条捷径,由网友 ...

  10. ZOJ 4009 And Another Data Structure Problem(ZOJ Monthly, March 2018 Problem F,发现循环节 + 线段树 + 永久标记)

    题目链接  ZOJ Monthly, March 2018 Problem F 题意很明确 这个模数很奇妙,在$[0, mod)$的所有数满足任意一个数立方$48$次对$mod$取模之后会回到本身. ...