常用的動態網頁對象:
之前我們提到了,使用request對象可以獲得和用戶請求相關的一系列信息。這一節,我們來看看另外兩個常用對象的常規用途。
response對象:用於向客戶回應。最常用的用法類似於
“Response.Redirect("/Home/Index1");”
它表示用戶瀏覽器跳轉到當前網站的“/Home/Index1”位置。
常用於出現各種錯誤的時候,提前結束當前流程。
Session對象:和ViewData的用法類似,也是用字典模式存儲數據。例:
Session["hello"] = "你好啊";
這種變量的有效期為“當前會話”,也可以理解為“本次訪問網站”。一般來說,用戶退出網站,或20分鍾內沒有任何操作,“當前會話”就結束了。
每個用戶都可以擁有一組屬於自己的Session變量,互相之間並不沖突,可以跨控制器和操作來傳遞值。
基於此,它通常用來保存用戶橫跨全站的信息。比如用戶名、權限等級、頭像等等。
例題:完成一個登錄程序,輸入用戶名、密碼,登錄成功進入操作頁面;否則進入出錯頁面。頁面上顯示當前用戶名。
控制器代碼:
public class HomeController : Controller { // GET: Home public ActionResult Index(string u="0",string p="0") { Session["user"] = u; if(u == "123" && p == "456") { Response.Redirect("home/get_menu"); } else if(u != "0" && p != "0") { Response.Redirect("/home/wrong"); } return View(); } public ActionResult get_Menu() { return View(); } public ActionResult Wrong() { return View(); } }
登錄視圖代碼:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> <form> 用戶名:<input type="text" name="u" /><br /> 密碼:<input type="password" name="p" /><br /> <input type="submit" value="登錄" /> </form> </div> </body> </html>
登錄成功視圖代碼:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>get_Menu</title> </head> <body> <div> 當前用戶為@(Session["user"].ToString())<br /> 已登錄,這里應該出現操作菜單。。。。 </div> </body> </html>
登錄失敗視圖代碼:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Wrong</title> </head> <body> <div> 當前用戶為@(Session["user"].ToString())<br /> 登錄失敗,用戶名、密碼不正確。 </div> </body> </html>
業務邏輯層
這一層,在很多mvc的教材里並不體現,也有很多人把它歸在“控制器”一類中。我自己的理解是:控制器只管調度,而業務邏輯是介於調度和讀寫數據之間的操作,值得另外開一層來寫。
上一章的“楊輝三角形”的練習中,控制器負責根據輸入的層數,計算楊輝三角形的內容,再返回給視圖,有一點混亂。我們換個寫法試試。以下內容屬於我的個人習慣,給大家參考。
在項目中,新建一個文件夾“functions”,表示廚房,完成一切業務處理。在其中新建一個類,“yanghui.cs”來完成楊輝三角形的生成,如下圖:
新建文件夾:
新建類:
選擇類型為類,名稱為yanghui:
這個類最主要的功能就是根據輸入的層數,完成楊輝三角形的計算。所以可以把這個操作寫成它的靜態方法(不用實例化就可以調用)
代碼如下:
public class Yanghui { public static int[,] get_Yanghui(int n) { int[,] a; a = new int[n, n]; for (int i = 0; i < n; i++) { a[i, 0] = 1; } for (int i = 1; i < n; i++) { for (int j = 1; j <= i; j++) { a[i, j] = a[i - 1, j - 1] + a[i - 1, j]; } } return a; } }
控制器簡化為:
public ActionResult Index(int n=0) { if (n == 0) { ViewData["d1"] = null; } else { ViewData["d1"] = Yanghui.get_Yanghui(n); } return View(); }
別忘了在控制器文件的頭部引入業務邏輯所在的名稱空間:
using WebApplication1.functions;
這樣的控制器,看起來才像個老板的樣子,僅負責調度。項目也更加清晰。
即:根據輸入的參數,決定哪些東西送廚房加工,哪些東西直接讓服務員拿給客戶。
視圖代碼不變,程序執行的效果也不變,但整個程序更加清晰流暢了。
模型:
直觀認識:
上一篇控制器和視圖的課程最后,給大家留了一個完成對學生數據增刪改查的小作業。那個時候,我們的程序邏輯都集中在控制器中。
現在我們可以回頭想想,程序應該如何布局。由於通篇都是是對數據庫的基本操作,動用“廚房”,是不是感覺也有點不太對。
對於這種“體力活”,我們可以引入一個新的模塊來處理----模型。
那個例子中,所有的操作都是對“學生”數據完成。“學生”就成了一個頻繁和數據庫交互的部分。它一方面要跟數據庫打交道,另一方面又需要跟程序有交集。就像一根釘子,嵌在物體里的部分要尖,被敲擊的部分要平。
模型也是如此。它負責跟數據庫打交道,有了它之后,程序里就不用再去管庫……甚至不用管庫里的邏輯(當然,寫模型的時候這些都要管);另一方面,它必須向“廚房”和“老板”提供很好的使用方法。我們通常也用類來完成模型的工作。
以下代碼可以作為模型用在那個例子當中:
class Student { string id,xm, nl, zy,sql;//sql是某條記錄准備執行的操作語句 public Student(string input_id)//構造函數1,只初始化編號,顯然准備刪除自己 { id = input_id; } public Student(string input_xm,string input_nl,string input_zy)//構造函數2,沒有編號,看樣子要把自己插入表中 { xm=input_xm; nl = input_nl; zy = input_zy; } public Student(string input_id,string input_xm, string input_nl, string input_zy)//構造函數3,啥都有,用於更新 { id = input_id; xm = input_xm; nl = input_nl; zy = input_zy; } public void insert_it()//插入方法 { sql = "insert into xs(xm,nl,zy) values('"+xm+"',"+nl+",'"+zy+"')"; Hc_db.do_nonquery(sql); } public void modify_it()//修改方法 { sql = "update xs set xm='"+xm+"',nl="+nl+",zy='"+zy+"' where id="+id; Hc_db.do_nonquery(sql); } public void delete_it()//刪除方法 { sql = "delete from xs where id=" + id; Hc_db.do_nonquery(sql); } }
有了Student類(模型)這個工具,控制器只需要接到數據和請求的操作后,new一個具體的“學生”對象出來,就可以直接操作了。有點像客人只點了一杯清水,老板可以直接讓打水的小廝端上來就好。
比如,處理刪除的控制器代碼大致是這樣(不嚴謹,僅供參考):
public ActionResult Index(string stu_id) { Student stu = new Student(stu_id); stu.delete_it(); return View(); }
轉書上P41
請大家按照這種邏輯,忘掉上面的代碼,自己寫一套學生信息管理程序(MVC俱全)
小綜合練習:
上例中,如果處理這些操作的業務邏輯比較復雜(比如在刪除學生之前需要判斷該學生成績是否合格,操作者權限是否足夠等等),則直接交給“廚房“執行。
參考這種思想,結合之前的知識,在上面例子的基礎上寫一套帶權限管理的學生信息管理程序。內容如下:
1、網站起始頁顯示所有學生信息。
2、網站用戶分為”未登錄“、”普通“、”管理員“三個級別。
3、未登錄用戶僅能查看所有學生信息。
4、普通用戶可以查詢指定學生信息、添加新學生。
5、管理員可以修改、刪除學生信息。