一、控制器
- 控制器角色
- 中轉作用
- 承上啓下,根據用戶輸入,執行響應行爲(動作方法)
- 在行爲中調用模型的業務邏輯,返回給用戶結果(視圖)
- 中介角色
- 分離視圖和模型,讓視圖和模型各司其職,控制器負責二者交互
- 只負責數據傳送,不負責處理
- 中轉作用
- 控制器類
- 所有控制器的基類都是Controller
- Controller類位於System.Web.Mvc命名空間,繼承自ControllerBase類
- ControllerBase類實現了Icontroller接口中的Execute方法,在路由器搜索到相應的控制器後,就會調用Execute方法進入控制器的處理
- ControllerBase類
- 屬性
- ControllerContext:獲取或者設置控制器上下文
- ValidateRequest:獲取或設置一個值,該值指示是否爲此請求啓用請求驗證
- ValueProvider:獲取或設置控制器的值
- ViewData:獲取或設置數據的字典
- ViewBag:獲取動態視圖數據字典
- TempData:獲取或設置可以在不同控制器之間傳遞數據的字典
- 任務
- 定位:找到對應的動作方法
- 獲取參數:獲取動作方法的參數
- 處理錯誤:在執行動作方法中可能出現的錯誤
- 渲染視圖:提供默認的WebFormViewFactory類來渲染ASP.NET視圖
- 屬性
二、動作方法的參數與模型映射
- 獲取URL和表單數據
//在動作方法中獲取URL和表單數據並處理 public ActionResult GetList() { //獲取提交的數據 string className = Request.Params["className"]; //獲取數據 string stuId = Request.QueryString["stuId"]; //數據處理....... List<Student> stuList = new StudentManage().GetStudentsByClass(className); } | | ↓ //在動作方法中使用"參數映射" public ActionResult GetList(string className) { List<Student> stuList = new StudentManage().GetStudentsByClass(className); //參數進行了自動映射,參數名稱與視圖中的參數名稱必須一致,不區分大小寫,參數類型也要相同 }
參數映射的好處:不需要手工獲取參數並作類型轉換,在多個參數是非常明顯
-
參數映射的優先級
- 表單數據 > 路由數據 > URL數據
- 參數名要和目標數據參數名一致(不區分大小寫)
- 參數數據類型要和來源數據類型一致
- 參數映射失敗解決方法:將值類型定義爲可爲空類型,可選參數,如 int?等等
- 映射模型
- 基本步驟:
- 獲取表單數據
- 構造實體模型
- 調用業務邏輯方法並傳遞模型
public ActionResult Edit() { Student object = new Student() { StudentId = Convert.ToInt32(Request.Params["stuId"]), StudentName = Request.Params["stuName"], Birthday = Convert.ToDateTime(Request.Params["birthday"]), .... ... }; int result = new StudentManage().ModifyStudent(object); return View(); } | | ↓ //映射實體 public ActionResult Edit(Student object) { //需要在視圖中將視圖中name屬性名設置的和實體屬性名稱相同, //且視圖要爲強類型視圖,則可以直接映射實體對象 int result = new StudentManage().ModifyStudent(object); return View(); }
- 基本步驟:
三、動作方法特性與ActionResult
- 動作方法的同名問題
- 重載一個控制器動作方法
public ActionResult GetList(string className) { List<Student> stuList = new StudentManage().GetStudentsByClass(className); return View(); } public ActionResult GetList() { //獲取提交的數據 string className = Request.Params["className"]; //獲取數據 string stuId = Request.QueryString["stuId"]; //數據處理....... List<Student> stuList = new StudentManage().GetStudentsByClass(className); } //路由系統不能根據方法參數取定位動作方法
- 解決方法
- HTTP請求謂詞方法:針對請求類型定位方法,解決同名衝突問題
- 關於Http謂詞
- 特點:經常使用,如果不加上該特性,默認動作方法接收所有謂詞請求
- 一般開發中都會加上謂詞,限定請求謂詞類型
特性名 說明 HttpGet 針對Get請求 HttpPost 針對Post請求 HttpDelete 針對Delete請求 HttpPut 針對Put請求 [HttpPost]//請求謂詞 public ActionResult GetList(string className) { List<Student> stuList = new StudentManage().GetStudentsByClass(className); return View(); } [HttpGet]//請求謂詞 public ActionResult GetList() { //獲取提交的數據 string className = Request.Params["className"]; //獲取數據 string stuId = Request.QueryString["stuId"]; //數據處理....... List<Student> stuList = new StudentManage().GetStudentsByClass(className); }
- 關於Http謂詞
- NonAction特性
- 可以將控制器中的方法聲明爲"非動作方法"
- 對於控制器內部使用的方法非常有用,加上該特性後,外部不能訪問,即可解決同名衝突問題
[NonAction] public ActionResult GetList() { //獲取提交的數據 string className = Request.Params["className"]; //獲取數據 string stuId = Request.QueryString["stuId"]; //數據處理....... List<Student> stuList = new StudentManage().GetStudentsByClass(className); }
- ActionName特性
- 爲動作方法"重新命名",解決同名衝突問題
- 視同中使用時,需要修改成"重新命名"後的方法
- 特別注意:當動作方法應用了ActionName特性後,如果動作方法內部使用View()方法調用視圖(也就是不指定視圖名稱),則調用的是和ActionName設置值同名的視圖
[ActionName("GetAllList")] public ActionResult GetList() { //獲取提交的數據 string className = Request.Params["className"]; //獲取數據 string stuId = Request.QueryString["stuId"]; //數據處理....... List<Student> stuList = new StudentManage().GetStudentsByClass(className); return View();//如果使用ActionName,返回View()不寫參數時候,默認返回ActionName的視圖 } //視圖中調用路徑 <form method="post" action="/Student/GetAllList"> ..... .... ... </form>
- HTTP請求謂詞方法:針對請求類型定位方法,解決同名衝突問題
- 重載一個控制器動作方法
- ActionResult詳解
- 隱式動作類型
- 動作方法返回類型可以是ActionResult以外的類型
public int Sum(int num1,int num2) { int sum = num1 + num2; return sum; } public void WriteLog() { System.IO.File.WriteAllText(@"D:\Syslog.txt","保存文件"); }
- 類型說明
- int類型 ->ContentResult類型
- void -> EmptyResult類型
- 動作方法返回類型可以是ActionResult以外的類型