目录
开启ASP.NET-MVC之旅
.NET框架组成架构
ASP.NET-MVC发展
ASP.NET开发的模式比较
WEB项目结构分析
- App_Data:用来保存数据文件
- App_Start:包含ASP.NET-MVC系统启动的相关类文件
- Controllers:存放整个项目“控制器”的代码文件
- Models:存放整个项目的“模型”代码文件
- Views:存放整个项目的“视图”代码文件
重要文件说明:
- Views下面的Web.config文件:作用于视图的配置文件
- Global.asax文件:全局应用程序文件,一般和App_Start文件夹中的类配合使用
- Packages.config文件:用于管理项目用到的程序集版本
- 根目录下的Web.config文件:作用于整个项目的配置文件
添加控制器:
- 右击解决方案中的“Controllers”文件夹,选择“添加”->“控制器”选项
- 在打开的对话框中,将控制器的默认名称改成“HomeController”,模板选择“空MVC控制器”,单击添加
namespace MyFirstMVC.Controllers
{
public class HomeController:Controller
{
//控制器中的动作方法,用于响应客户端请求,并调用响应的视图
//向浏览器输出信息
public ActionResult Index()
{
//控制器主要任务
//1.获取数据:接受请求数据
//2.业务处理:和Model交互
//3.控制跳转:返回视图或跳转至其他控制器
return View();//该方法调用默认视图Index(与Index()方法同名)
}
}
}
添加视图:
- 右键单击“Views”文件夹,添加“Home”文件夹
- 在Home文件夹下创建视图
- 将属兔名称改为Index,视图引擎选择“ASPX(C#)”,其他复选框都不选,单击添加
- 添加成功后,在页面中添加一些内容,然后直接运行程序
- 视图访问和寻址规则
- 在控制器中使用View()方法调用视图,返回和动作方法同名的视图
- 寻找规则:View()方法默认会从“Views文件夹”下寻找和控制器同名的文件夹,比如HomeController控制器会寻找“Views/Home”文件夹
- MVC中的约定
- 控制器:必须以Controller结尾
- 视图:必须在Views文件夹下,并且要和控制器“同名的子目录”中创建
- 约定胜于配置
- 提前规定好
- 无需配置文件
- 不遵守规则则出错
ASP.NET-MVC工作流程分析
- 应用程序启动,加载路由表
- 用户操作,通过浏览器向Web服务器发出请求
- Web服务器通过查找路由表进行路径比对
- 找到相应的控制器后,web服务器将请求交给指定控制器的动作方法
- 控制器处理请求,与后台模块交互,执行相应的任务
- 控制器按照寻址规则返回对应的视图,响应用户界面
ASPX视图
- 视图分类
- ASPX视图
- Razor视图
- @Page指令
- 作用:页面的声明
- 要求:必须放在第一行
- 常见指令属性如下
- Language:指定页面代码和后置代码使用的语言
- Inherits:继承的页面类
- ContentType:指定页面字符编码方式
- ValidateRequest:指定是否验证请求
- MasterPageFile:指定使用的母版视图文件
- @Import指令
- 作用:在视图中引入使用的命名空间
- 方法:<%@Import Namespace = "BLL.AdminManager"%>
- 服务器端内嵌语法
- 小脚本:在ASPX视图中,可以使用<% %>嵌入C#代码,用来编写任意服务端程序逻辑
- 表达式:使用<%=%>用来输出信息,也可以写成<%:%>
<body> <div> <h2></h2> <br/> <% //求考试成绩 int[] score = {90,96,89,86}; int sum = 0' foreach(int item in socre) { sum += item; } %> <!--输出总成绩> 总成绩:<%=sum%> </div> </body> //在MVC中表达式使用最多,其次是小脚本
Razor视图与数据传递
视图引擎
- 简单理解为就是能够支持对视图的解析
- 在ADP.NET MVC中,视图引擎的作用就是把视图处理成浏览器能够执行的HTML代码
- 不同的视图引擎,语法规则不同
视图引擎分类:
- ASPX引擎:就是web表单引擎,使用<%%>这种小脚本和<%= %>表达式这种方法,简单容易上手
- Razor引擎:从MVC3开始引入,语法简单而雅致,代码编写更方便
Razor视图重点@使用的语法总结
@(表达式)
- 可以把()去掉,简写成@表达式,但是仅限于@后紧邻变量或对象,如果后面是常数则必须加()
<div>@ViewBag.Info</div> @("欢迎使用Razor视图");
@{代码段}
- 代码段可以出现在任意位置,并且支持与HTML混写
- 单独的if或循环结构也可以直接使用@
@{ foreach(Models.Student stu in ViewBag.stuList) { ...... } }
输出@符号
-
使用"@@"进行转移:
<p>zhangsan@@qq.com</p>
引入命名空间
-
使用using引入命名空间
@using System.Collections.Generic
注释
-
在Razor视图中可以使用"@**@"注释代码
<div> <p>zhangsan@@qq.com</p> @*@ViewBag.Info*@ </div>
单个实体查询与强类型视图
ViewData不足:存放的数据一律以Object类型存放,取数据时需要强制类型转换,强类型视图可以解决这个问题
强类型视图的添加
从控制器到视图的数据传递
ViewData对象
- 概述
- ViewData是一种字典数据集合,是"视图基类"和"控制器基类"的属性
- 常见用法是在控制器中写入数据,在视图中读取数据
- ViewData的Value可以存放任意数据类型的数据,因此使用时需要进行强制转换
public ActionResult GetStuDetail() { string stuId = Request.QueryString["stuId"]; Student objStudent = new StudentManage().GetStudentById(stuId); ViewData["objStudent"] = objStudent; return View("StudentDetail"); } //界面获取 Models.Student objStudent = (Models.Student)ViewData["objStudent"];
动态对象ViewBag(代码编写时不会进行错误检查,在编译时出错会报错)
- 概述
- 理解:ViewBag是dynamic类型对象,同样也是"视图基类"和"控制器基类"的属性
- 好处:使用更灵活方便
- 特点:ViewBag其实是对ViewData数据的包装,使用ViewData保存的数据可使用ViewBag读取,反之亦然
- 应用:实际开发中最好选择其中一种使用,建议使用ViewBag
public ActionResult GetStuList() { string className = Request.Params["className"]; List<Student> stuList = new StudentManager().GetStudentsByClass(className); ViewBag.className = className;//变量名随意取,获取时名称相同即可拿到数据 ViewBag.stuList = stuList; return View("StudengManage"); } //获取 <input type = "text" name = "className" value = "@ViewBag.className"></input>
跨请求数据传递TempData
- 概述
- 理解:TempData是一种字典对象,也能用于从"控制器到视图"的数据传递,和ViewData类似
- 特性:TempData还能实现"不同请求之间"的数据传递
-
//测试不同控制器之间的数据传递 public ActionResult StudentAdminLogin() { SysAdmin objAdmin = new SysAdmin() { LoginId = Convert.ToInt32(Request.Params["loginId"]), LoginPwd = Request.Params["loginPwd"] }; TempData["objAdmin"] = objAdmin; //跳转至其他控制器(重定向到另一个Action),参数为动作方法+控制器 return RedirectToAction("AdminLogin","SysAdmin"); } //接收数据 public ActionResult AdminLogin() { SysAdmin objAdmin = (SysAdmin)TempData["objAdmin"];//获取存放在TempData中的数据 }
- 注意问题
- TempData数据保存机制是Session,但又不完全是Session
- 情况1:TempData保存数据后,如果被使用,就会被清除,因此后面的请求将不能再次使用
- 情况2:TempData保存数据后,如果没有被使用,则它保存的时间是Session的生存期
小结:
- ViewData:适合传递单个数据,需要类型转换
- ViewBag:适合传递单个数据,不需要类型转换
- TempData:主要用于跨多个动作方法传递参数
- View()+Modle:适合传递模型数据,不需要类型转换