ASP.NET MVC 框架可將 URL 映射到稱為“controller”的類。 控制器將處理傳入的請求,處理用戶輸入和交互,並執行相應的應用程序邏輯。
所有控制器的基類為 ControllerBase 類,該類可進行普通的 MVC 處理。 Controller 類從 ControllerBase 中繼承並且是控制器的默認實現。 Controller 類負責以下處理階段的工作:
-
查找要調用的相應操作方法,並驗證是否可以調用該方法。
-
獲取要用作操作方法的參數的值。
-
處理在執行操作方法期間可能發生的所有錯誤。
-
提供用於呈現 ASP.NET 頁面類型(視圖)的默認 WebFormViewEngine
當Controller被MVCHandler選中以后,緊接着就會用過ActionInvoker選擇合適的Action來進行執行操作,當然在我們用習慣MVC以后,就會自然而然的不去思考參數是怎么轉換和綁定了,我們不在需要使用asp.netWebForm那樣的方式通過Reuqest.QueryString[]\Request.Form[]去獲取,在進行處理,我們只需要習慣這種模型綁定方式,那么現在我們是怎么處理View傳過來的數據的?
很多新學習web的同學可能更喜歡使用原始的Form提交的方式,那么我們來看這個例子:
<form action="Home/Accept" method="post"> 編號<input name="id" type="text" /> 姓名<input name="name" type="text" /> <input type="submit" value="提交"/> </form>
這是前台的,我們定義了兩個有效地數據獲取控件,指定了網址路由,然后我們在后台的Action中獲取,先看看后台是怎么定義的
public ActionResult Accept(int id, string name) { return Content(string.Format("學生{0}的編號是{1}",name,id)); }
當我們運行並點擊提交按鈕就會發現,前台傳過去的id和name自動的被獲取到了,你已經發現前台傳過來的數據自動的進行了轉換,這就是MVC方便的綁定機制,當然,在
開發中你還會遇到強類型視圖傳過來的多個復雜對象的模型綁定機制。這里就不在多說了,全部放在之后的幾個例子里大概說一下,自己理解這些基礎更好。
Action執行完通常返回的是是一個ActionResult 中派生的類的實例。 ActionResult 類是所有操作結果的基礎。他其實是一個抽象類。我們來看一下它的定義:

1 // 摘要: 2 // Encapsulates the result of an action method and is used to perform a framework-level 3 // operation on behalf of the action method. 4 public abstract class ActionResult 5 { 6 // 摘要: 7 // Initializes a new instance of the System.Web.Mvc.ActionResult class. 8 protected ActionResult(); 9 10 // 摘要: 11 // Enables processing of the result of an action method by a custom type that 12 // inherits from the System.Web.Mvc.ActionResult class. 13 // 14 // 參數: 15 // context: 16 // The context in which the result is executed. The context information includes 17 // the controller, HTTP content, request context, and route data. 18 public abstract void ExecuteResult(ControllerContext context); 19 }
現在很明了,他就是獲取ActionResult子類的對象,並執行它的ExecuteReslut方法,然后將執行結果返回給客戶端。
您可以創建返回任意類型(如字符串、整數或布爾值)的對象的操作方法。 這些返回類型在呈現到響應流之前包裝在合適的 ActionResult 類型中。
下表顯示了內置操作結果類型以及返回這些類型的操作幫助器方法。
此外,新學習的同學們也應該對常見的Action選擇器進行一個了解和認識,例如HTTPPost,HTTPGet,HttpDelete,HttpPut,NonAction這些都比較簡單,看下就會了。
下面我們就演示幾個例子來初步了解一下其中的某些ActionResult對象的用法。
我們來做下面這個常見的效果:
也就是前后兩個下拉列表框的數據來自不同的表,但是又相互關聯。
我們先來看后台處理代碼:(這里並不需要綁定selected選擇項,在這里不是重點,之后有時間會介紹在Edit等頁面中怎么綁定已選中的項和值)
我們先來看剛進入的時候,先默認綁定文章類下面的所以關聯的數據
List<SelectListItem> types = new List<SelectListItem>(); var query = from type in new ArticleTypeDAL().GetList() select type; foreach (var type in query) { types.Add(new SelectListItem { Value = type.ArticleTypeId.ToString(), Text = type.ArticleTypeName }); } ViewData["ContentType"] = new SelectList(types,"Value","Text"); var query2 = from item in new ArticleItemDAL().GetList().Where(c => c.ArticleTypeId == Convert.ToInt32(types[0].Value)) select item; List<SelectListItem> items = new List<SelectListItem>(); foreach (var item in query2) { items.Add(new SelectListItem { Value = item.ArticleItemId.ToString(), Text = item.ArticleItemName }); } ViewData["ContentItem"] = new SelectList(items, "Value", "Text"); return View();
客戶端:
文章類別:<%=Html.DropDownList("Seltype", ViewData["ContentType"] as SelectList)%> <%=Html.DropDownList("Selitem", ViewData["ContentItem"] as SelectList)%>
現在我們的要求是動態的根據前面的內容改變后面的下拉框的數據
我們根據前面的類型Id動態的獲取后面的關聯項,於是我們這么寫
public JsonResult SearchArticleItem(int typeId) { List<SelectListItem> items = new List<SelectListItem>(); var query3 = from item in new ArticleItemDAL().GetList().Where(c => c.ArticleTypeId == typeId) select item; foreach (var item in query3) { items.Add(new SelectListItem { Value = item.ArticleItemId.ToString(), Text = item.ArticleItemName }); } return Json(items, JsonRequestBehavior.AllowGet); }
JsonRequestBehavior.AllowGet,這個是告知客戶端可以通過HTTPGet方式獲取json數據,為了安全起見,默認是不允許使用Get方式獲取的。
然后我們通過ajax方式前台動態的加載關聯數據:
$(function() { $("#Seltype").change(function() { $("#Selitem").find("option").remove(); var sp = $("#Seltype option:selected"); var url = '<%=Url.Action("SearchArticleItem","Article")%>'; $.post(url, { typeId: sp.val() }, function(response) { $.each(response, function(i, item) { $("<option></option>").val(item.Value).text(item.Text).appendTo($("#Selitem")); }); }); }); });
學習Controller的時候你有必要了解一下 ControllerBase 中一些虛方法,下面介紹一個很好玩的也是很有用的一個虛方法HandleUnknownAction
這個方法使用來干什么的?你熟悉這個嗎?
嗯,他就是找不到相應的Action后的一個處理函數,這里注意下不是找不到View是找不到Action,如果是找不到View的話就會出現你懂得(不截圖自己試試就知道了)。。。
至於內部怎么處理,完全按照你的要求啦。
此外如果一個ViewData或者ViewBag要在同一個controller下的多個Action中復用的話,建議直接寫在Controller的構造函數中,這樣就不用多費體力了。
很多東西既不是一兩篇文章可以說完的, 也沒有那么多的時間去寫東西,所以開始要和大家一起自己研究。
下面對TempData進行一個解釋
TempData的數據結構和ViewData一樣,也屬於字典類,他和ViewData不一樣的地方就是它使用Session來存儲數據,他的有效期僅僅限於一次網絡請求,
也就是說他在一次王爺請求后就自動清空了。
我們對前面的例子稍微修改一下:
public ActionResult About()
{
return View(TempData["msg"]);
}
public ActionResult Accept(int id, string name)
{
TempData["msg"] = string.Format("學生{0}的編號是{1}", name, id);
return RedirectToAction("About");
}
這樣運行以后我們輸入111,阿斯達;
提交后我們會得到一樣一行信息:,之后我們一刷新,沒了,現在我們換成ViewData試試
我們再來修改一下代碼:
public ActionResult About() { return View(TempData["msg"]); } public ActionResult Accept(int id, string name) { TempData["msg"] = string.Format("學生{0}的編號是{1}", name, id);//寫入 string msg = TempData["msg"].ToString();//讀取 return RedirectToAction("About"); }
我們執行發現數據沒有了,這是因為在Acctpt這個Action中寫入后又一次請求獲取的值的過程,里面的數據自動清空,跳轉到別的頁面數據也就沒有了。