MVC的組成:Model(模型), View(視圖), Controller(控制器)
MVC的作用:其主要設(shè)計(jì)目標(biāo)是將用戶(hù)接口和邏輯層相分離郭脂,以便開(kāi)發(fā)人員更好關(guān)注邏輯層的設(shè)計(jì)和測(cè)試俊犯,并使整個(gè)程序具備清晰的架構(gòu)油宜。
一另伍、MVC主要概念
Model
模型對(duì)象是實(shí)現(xiàn)應(yīng)用程序數(shù)據(jù)域邏輯的應(yīng)用程序組件宪睹,通常被稱(chēng)為“數(shù)據(jù)模型”。模型對(duì)象會(huì)檢索模型狀態(tài)并將其存儲(chǔ)在數(shù)據(jù)庫(kù)中岗照。
例如村象,Product(商品)對(duì)象可能會(huì)從數(shù)據(jù)庫(kù)中檢索信息,操作該信息攒至,然后將更新的信息寫(xiě)回到 SQL Server 數(shù)據(jù)庫(kù)內(nèi)的 Products(商品信息) 表中厚者。
Controller
控制器是處理用戶(hù)交互、使用模型并選擇視圖來(lái)顯示界面的組件迫吐。在 MVC 應(yīng)用程序中库菲,視圖僅顯示界面;控制器則用于處理和響應(yīng)用戶(hù)輸入和交互志膀。
例如熙宇,控制器處理查詢(xún)字符串值,并將這些值傳遞給模型溉浙,而模型可能會(huì)使用這些值來(lái)查詢(xún)數(shù)據(jù)庫(kù)烫止。
View
視圖是顯示應(yīng)用程序用戶(hù)界面 (UI) 的組件。 通常放航,此 UI 由模型數(shù)據(jù)創(chuàng)建烈拒。
例如,Products(商品信息)表的編輯視圖便是一個(gè)視圖广鳍,該視圖基于 Product(商品)對(duì)象的當(dāng)前狀態(tài)顯示文本框荆几、下拉列表和復(fù)選框等控件。
ASP.NET MVC 支持Razor視圖引擎赊时,所以視圖更多的采用CSHTML頁(yè)面吨铸。
二、創(chuàng)建.NET MVC項(xiàng)目
在VS開(kāi)發(fā)環(huán)境中祖秒,創(chuàng)建 .NET MVC項(xiàng)目由兩種形式:
(1)創(chuàng)建MVC項(xiàng)目:其中自動(dòng)集成了Jquery,Bootstrap诞吱,以及微軟提供了一個(gè)Demo示例。
(2)創(chuàng)建空MVC項(xiàng)目:其中只有Model竭缝,View房维,Controller等最主要的文件夾和文件內(nèi)容。
ASP.NET MVC應(yīng)用程序目錄說(shuō)明:
目錄 | 說(shuō)明 |
---|---|
App_Start | 包含多個(gè)靜態(tài)配置類(lèi)抬纸,執(zhí)行應(yīng)用程序的初始化任務(wù) |
Content | 放置應(yīng)用程序的靜態(tài)內(nèi)容咙俩,如:CSS、可下載的文件、音樂(lè)文件阿趁、… |
Controller | 放置控制器文件膜蛔。控制器文件是后綴名.cs或.vb的類(lèi)文件 |
Models | 放置數(shù)據(jù)模型對(duì)象的文件脖阵,例如:.cs皂股、.vb、.edmx命黔、.dbml呜呐、… |
Views | 放置視圖文件,文件后綴名為.cshtml或.aspx |
Scripts | 放置JavaScript纷铣、jQuery文件 |
三卵史、Hello,World
下面我們利用控制器和視圖,編寫(xiě)第一個(gè).NET MVC項(xiàng)目搜立,在頁(yè)面顯示Hello,World
(1)在Controller文件夾中創(chuàng)建一個(gè)空控制器,命名為"HomeController"槐秧,(控制器的命名規(guī)則要求以Controller結(jié)尾)啄踊。
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
}
}
(2)在Index()函數(shù)里面點(diǎn)擊右鍵--》添加視圖,系統(tǒng)會(huì)在View文件夾創(chuàng)建Home文件夾刁标,Home文件夾中創(chuàng)建index.cshtml,如下:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
</div>
</body>
</html>
(3)在body的div中插入文本颠通,然后瀏覽此文件,瀏覽地址為:http://域名:端口/控制器名字(Home)/Action名字(Index)
四膀懈、控制器向視圖共享數(shù)據(jù)
控制器向視圖傳遞少量數(shù)據(jù)顿锰,常見(jiàn)三種為:
ViewData:字典類(lèi)型,存放的是鍵/值對(duì)數(shù)據(jù)启搂。ViewData只在一次HTTP請(qǐng)求中有效硼控,當(dāng)這次請(qǐng)求結(jié)束后,會(huì)自動(dòng)清空其值胳赌。
ViewBag:相當(dāng)于ViewData牢撼,但是內(nèi)在的實(shí)現(xiàn)卻完全不一樣。 ViewBag存放的不是鍵值對(duì)數(shù)據(jù)疑苫,而是dynamic動(dòng)態(tài)類(lèi)型數(shù)據(jù)熏版。
TempData:默認(rèn)保存在Session中,控制器每次請(qǐng)求從Session中獲取TempData捍掺,然后清除Session撼短。基于這樣的事實(shí)挺勿,在每次請(qǐng)求結(jié)束后曲横,TempData的生命周
期同時(shí)結(jié)束。
1满钟、ViewData共享數(shù)據(jù)
自定義類(lèi)支持代碼:
public class Employee
{
public int EmpId { get; set; }
public string EmpName { get; set; }
public string EmpPhone { get; set; }
}
控制器代碼如下:
public ActionResult Index()
{
//ViewData胜榔,字典類(lèi)型胳喷,存放的是鍵/值對(duì)數(shù)據(jù)。
//ViewData只在一次HTTP請(qǐng)求中有效夭织,當(dāng)這次請(qǐng)求結(jié)束后吭露,會(huì)自動(dòng)清空其值。
Employee emp = new Employee();
emp.EmpId = 1;
emp.EmpName = "孫悟空";
emp.EmpPhone = "13558969651";
ViewData["Emp"] = emp;
ViewData["Info"] = "這是我的第一個(gè)MVC程序尊惰!";
return View();
}
視圖展示數(shù)據(jù):
<div>
<h1>
@ViewData["Info"].ToString()
</h1>
<h2>員工基本信息如下:</h2>
@{
Employee emp = (Employee)ViewData["Emp"];
}
<p>編號(hào):@emp.EmpId</p>
<p>姓名:@emp.EmpName</p>
<p>電話:@emp.EmpPhone</p>
</div>
2讲竿、ViewBag共享數(shù)據(jù)
自定義類(lèi)支持代碼:
public class Employee
{
public int EmpId { get; set; }
public string EmpName { get; set; }
public string EmpPhone { get; set; }
}
控制器代碼如下:
public ActionResult Default()
{
//ViewBag,相當(dāng)于ViewData弄屡,但是內(nèi)在的實(shí)現(xiàn)卻完全不一樣昼激。
//ViewBag存放的不是鍵值對(duì)數(shù)據(jù),而是dynamic動(dòng)態(tài)類(lèi)型數(shù)據(jù)燥翅。
Employee emp = new Employee();
emp.EmpId = 1;
emp.EmpName = "孫悟空";
emp.EmpPhone = "13558969651";
ViewBag.Emp = emp;
ViewBag.Info = "這是我的第一個(gè)MVC程序拿穴!";
return View();
}
視圖展示數(shù)據(jù):
<div>
<h1>
@ViewBag.Info
</h1>
<h2>員工基本信息如下:</h2>
<p>編號(hào):@ViewBag.Emp.EmpId</p>
<p>姓名:@ViewBag.Emp.EmpName</p>
<p>電話:@ViewBag.Emp.EmpPhone</p>
</div>
3、TempData的使用
以下代碼模擬一個(gè)登錄請(qǐng)求全庸,使用TempData保存提示數(shù)據(jù)秀仲,因?yàn)門(mén)empData在一次跳轉(zhuǎn)后仍然可以保存數(shù)據(jù)。
用戶(hù)登錄頁(yè)面對(duì)應(yīng)的Action:
//TempData壶笼,默認(rèn)保存在Session中神僵,控制器每次請(qǐng)求從Session中獲取TempData,然后清除Session覆劈。
//基于這樣的事實(shí)保礼,在每次請(qǐng)求結(jié)束后,TempData的生命周期同時(shí)結(jié)束责语。
public ActionResult LoginForm()
{
return View();
}
用戶(hù)登錄頁(yè)面的視圖:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>LoginForm</title>
<style type="text/css">
div, table, tr, td { margin:0px; padding:0px;}
.myTable { width:800px; margin:20px auto; border-collapse:collapse; }
.myTable td { height:30px; line-height:30px; padding:6px;
}
</style>
</head>
<body>
<form method="post" action="~/Home/Login">
<div style="text-align:center;">
<table width="800" class="myTable" border="1">
<tr>
<td colspan="2" align="center" style="font-weight:bold;">用戶(hù)登錄</td>
</tr>
<tr>
<td width="200" align="right">用戶(hù)名:</td>
<td width="600" align="left"><input type="text" name="txtAccount" /></td>
</tr>
<tr>
<td width="200" align="right">密碼:</td>
<td width="600" align="left"><input type="password" name="txtPwd" /></td>
</tr>
<tr>
<td width="200" align="right"></td>
<td width="600" align="left">
<input type="submit" value="登錄" />
@TempData["ErrInfo"]
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
用戶(hù)登錄請(qǐng)求的Action:
public ActionResult Login()
{
//假設(shè)用戶(hù)名 admin,密碼 admin 才能登錄成功炮障,其它登錄失敗
string acc = Request["txtAccount"].ToString();
string pwd = Request["txtPwd"].ToString();
if (acc.Equals("admin") && pwd.Equals("admin"))
{
return RedirectToAction("WelComeForm");
}
else
{
TempData["ErrInfo"] = "用戶(hù)名或密碼錯(cuò)誤"; //TempData可以在跳轉(zhuǎn)后保存接受數(shù)據(jù),但只會(huì)在一次跳轉(zhuǎn)中保存鹦筹。
return RedirectToAction("LoginForm");
}
}
登錄成功跳轉(zhuǎn)的歡迎頁(yè)面Action:
public ActionResult WelComeForm()
{
return View();
}
登錄成功跳轉(zhuǎn)的歡迎頁(yè)面視圖:
<div>
<h1>歡迎來(lái)到********公司OA管理系統(tǒng)铝阐!</h1>
</div>
五、同名Action
同樣去實(shí)現(xiàn)上面的模擬登錄的功能铐拐,在上面的例子中徘键,我們編寫(xiě)了兩個(gè)Action,分別是LoginForm和Login用來(lái)打開(kāi)登錄的頁(yè)面和接受處理登錄的請(qǐng)求遍蟋。
我們也可以編寫(xiě)兩個(gè)同名的Action吹害,兩個(gè)Action名字都叫Login,我們使用請(qǐng)求方式的不同進(jìn)行區(qū)分兩個(gè)Action虚青。
用戶(hù)登錄頁(yè)面對(duì)應(yīng)的Action:
//TempData它呀,默認(rèn)保存在Session中,控制器每次請(qǐng)求從Session中獲取TempData,然后清除Session纵穿。
//基于這樣的事實(shí)下隧,在每次請(qǐng)求結(jié)束后,TempData的生命周期同時(shí)結(jié)束谓媒。
public ActionResult Login()
{
return View();
}
用戶(hù)登錄頁(yè)面的視圖:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>LoginForm</title>
<style type="text/css">
div, table, tr, td { margin:0px; padding:0px;}
.myTable { width:800px; margin:20px auto; border-collapse:collapse; }
.myTable td { height:30px; line-height:30px; padding:6px;
}
</style>
</head>
<body>
<form method="post" action="~/Home/Login">
<div style="text-align:center;">
<table width="800" class="myTable" border="1">
<tr>
<td colspan="2" align="center" style="font-weight:bold;">用戶(hù)登錄</td>
</tr>
<tr>
<td width="200" align="right">用戶(hù)名:</td>
<td width="600" align="left"><input type="text" name="txtAccount" /></td>
</tr>
<tr>
<td width="200" align="right">密碼:</td>
<td width="600" align="left"><input type="password" name="txtPwd" /></td>
</tr>
<tr>
<td width="200" align="right"></td>
<td width="600" align="left">
<input type="submit" value="登錄" />
@TempData["ErrInfo"]
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
用戶(hù)登錄請(qǐng)求的Action:
[HttpPost]
public ActionResult Login()
{
//假設(shè)用戶(hù)名 admin,密碼 admin 才能登錄成功淆院,其它登錄失敗
string acc = Request["txtAccount"].ToString();
string pwd = Request["txtPwd"].ToString();
if (acc.Equals("admin") && pwd.Equals("admin"))
{
return RedirectToAction("WelComeForm");
}
else
{
TempData["ErrInfo"] = "用戶(hù)名或密碼錯(cuò)誤"; //TempData可以在跳轉(zhuǎn)后保存接受數(shù)據(jù),但只會(huì)在一次跳轉(zhuǎn)中保存句惯。
return RedirectToAction("Login");
}
}
登錄成功跳轉(zhuǎn)的歡迎頁(yè)面Action:
public ActionResult WelComeForm()
{
return View();
}
登錄成功跳轉(zhuǎn)的歡迎頁(yè)面視圖:
<div>
<h1>歡迎來(lái)到********公司OA管理系統(tǒng)土辩!</h1>
</div>