ASP.NET MVC学习---(五)MVC初体验
经过之前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初体验的更多相关文章
- 第三次随笔--安装虚拟机及学习linux系统初体验
第三次随笔--安装虚拟机及学习linux系统初体验 ·学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 首先按照老师的提示步骤进行VirtualBox虚拟 ...
- 算法学习:并行化初体验_JAVA实现并行化归并算法
这个系列包括算法导论学习过程的记录. 最初学习归并算法,对不会使其具体跑在不同的核上报有深深地怨念,刚好算倒重温了这个算法,闲来无事,利用java的thread来体验一下并行归并算法.理论上开的thr ...
- Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用[z]
前言 早在去年就简单的使用了一下Spring Boot,当时就被其便捷的功能所震惊.但是那是也没有深入的研究,随着其在业界被应用的越来越广泛,因此决定好好地深入学习一下,将自己的学习心得在此记录,本文 ...
- Yaf学习(二)----Yaf初体验
1.hello world 1.1 用yaf输出hello world 1.首先配置host,nginx 2.host不用多说,指向虚拟机IP即可 1.2 重点说一下nginx (只说server块) ...
- MVC学习五:Razor布局页面 _ViewStart.cshtml
如图: _ViewStart.cshtml就是MVC中的布局页面/模板页面. 用户访问流程图: 原理:先去执行Views文件夹下[_ViewStart.cshtml]页面,然后同级目录文件夹(上图中的 ...
- MVC学习笔记---MVC生命周期及管道
ASP.NET和ASP.NET MVC的HttpApplication请求处理管道有共同的部分和不同之处,本系列将体验ASP.NET MVC请求处理管道生命周期的19个关键环节. ①以IIS6.0为例 ...
- MVC学习笔记---MVC的处理管线
漫步ASP.NET MVC的处理管线 ASP.NET MVC从诞生到现在已经好几个年头了,这个框架提供一种全新的开发模式,更符合web开发本质.你可以很好的使用以及个性化和扩展这个框架,但这需要你 ...
- Visual Studio Code 学习.net core初体验
一,安装 最近在用 Visual Studio Code 学习.net core ,记录下学习的过程,首先去官网下载最新的.net core2.1安装包,有windows 和mac,根据自己的开发环境 ...
- MVC学习笔记---MVC生命周期
Asp.net应用程序管道处理用户请求时特别强调"时机",对Asp.net生命周期的了解多少直接影响我们写页面和控件的效率.因此在2007年和2008年我在这个话题上各写了一篇文章 ...
- MVC学习笔记---MVC导出excel(数据量大,非常耗时的,异步导出)
要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...
随机推荐
- The Cave
The Cave 题目描述 给定一棵有n个节点的树,相邻两点之间的距离为1. 请找到一个点x,使其满足所有m条限制,其中第i条限制为dist(x,a[i])+dist(x,b[i])<=d[i] ...
- 牛客小白月赛4——I—合唱队形
链接:https://www.nowcoder.com/acm/contest/134/I来源:牛客网 题目描述 铁子的班级在毕业晚会有一个合唱节目,到了毕业晚会的时候,他们必须排成一排一起合唱&qu ...
- Topcoder SRM 605 div1 题解
日常打卡- Easy(250pts): 题目大意:你有n种汉堡包(统统吃掉-),每一种汉堡包有一个type值和一个taste值,你现在要吃掉若干个汉堡包,使得它们taste的总和*(不同的type值的 ...
- 自定义Windows服务并实施安装
1.新建项目DemoService,并添加windows服务,命名DemoService 2.添加代码 using System; using System.Collections.Generic; ...
- WPF中的URI
在 Windows Presentation Foundation (WPF) 中,使用统一资源标识符 (URI) 标识和加载文件的方式有很多,包括: 指定当应用程序第一次启动时显示的用户界面 (UI ...
- 基于UDP高性能传输协议UDT doc翻译(一)
原文转自:http://hi.baidu.com/doodlezone/item/74a203155efe26dbbf9042dd UDT文档阅读理解 一. 概述 ...
- centos6.5 以 zero-dependency Erlang from RabbitMQ 搭建环境
rabbitmq 官方安装文档可参考:http://www.rabbitmq.com/install-rpm.html ,由于rabbitmq 使用Erlang 开发的,运行环境需要用到Erlang ...
- 【linux高级程序设计】(第十五章)UDP网络编程应用 4
socket信号驱动 为了使一个套接字能够使用信号驱动I/O,至少需要以下3步操作. 1.安装SIGIO信号 2.套接字的拥有者设定为当前进程.因为SIGIO信号只会送到socket拥有者进程. 通过 ...
- Openstack celi
http://www.51testing.com/html/76/n-3720076.html
- git回溯到指定版本
git回溯到指定版本 git log命令查看仓库日志 然后使用git checkout 命令 例如回溯到上图中的版本 git checkout 12db5d6fd138922a8aaf2214c84c ...