文章目錄
- I:控制器和視圖的基礎概念
- II:控制器
- III:視圖
- IV:原始碼下載
I:控制器和視圖的基礎概念
1.控制器的概念
控制器在ASP.NET MVC3當中是最終處理用戶端請求的一個實現,他有個一硬性條件就是必須實現System.Web.Mvc.IController介面,而且類的命名必須要以Controller結尾,儘管按照硬性條件上來說,要自己實現一個介面比較糾結,但幸好的是在ASP.NET MVC3內部已經包含了一個預設的實現,我們只需要把類的命名設定為Controller結尾然後繼承System.Web.Mvc.Controller類,立刻就可以輕鬆地實現了IController介面了.如果你不喜歡這種預設提供的實現方式,而是自己去實現IController的話.下面的代碼可以做一個簡單的參考:
using System.Web.Mvc;using System.Web.Routing;namespace MvcApplication1.Controllers{ public class NoDefaultController : IController { void IController.Execute(RequestContext requestContext) { var httpContext = requestContext.HttpContext; var response = httpContext.Response; response.ContentType = "text/html; charset=utf-8"; response.Write("自己的簡單實現! Hello World"); } }}
請注意:控制器類不硬性要求放在*.Controllers命名空間中
如果是使用繼承預設的類去實現的話代碼如下:
using System.Web.Mvc;namespace MvcApplication1{ public class HelloController : Controller { public ActionResult Index() { return Content("預設的實現! Hello World"); } }}
我就不發了.大家可以手動試一試.
2.視圖的概念
視圖的理解比較簡單.你可以把視圖理解為*.aspx或*.cshtml的檔案.但是不是所有的aspx, cshtml檔案都可以作為視圖,它們必須得屬於某一個以控制器名稱命名的檔案夾當中,而且要按照約定去存放到路徑 ~/Views/{controller}/View.cshtml.
另外視圖還包含解析他的ViewEngine(視圖引擎),本文在這裡不涉及這個進階話題.
我們可以看出在~/Views/{controller}/View.cshtml中的{controller}並不需要像類命名那樣以Controller結尾去做檔案夾名稱.
3.工作原理圖
當然,內部的工作原理會比這個圖複雜得多.在此也僅僅是讓大家有個瞭解而已!如有錯誤請指出.謝謝!
提示:MvcHandler實現了IHttpAsyncHandler, IHttpHandler, IRequiresSessionState這三個介面,我在Debug進去的時候發現都是走非同步路線.對於這個處理方式,瞭解的人希望可以為我解答一下!
II:控制器
1.操作方法
操作方法的含義是指在繼承了System.Web.Mvc.Controller類中所定義的傳回值的類型可以相容ActionResult的方法.
using System.Web.Mvc;namespace MvcApplication1.Controllers{ public class HomeController : Controller { ///<summary> /// Hi, 我是Index操作方法 ///</summary> ///<returns></returns> public ActionResult Index() { ViewBag.Message = "Welcome to ASP.NET MVC!"; return View(); } ///<summary> /// 厄, 我是About操作方法 ///</summary> ///<returns></returns> public ActionResult About() { return View(); } ///<summary> /// 可以為方法添加不是操作方法的特性 ///</summary> ///<returns></returns> [NonAction] public string NonAction() { return "親,不好意思噢.我不是操作方法噢,請不要亂調用噢!"; } }}
同時也可以使用[ActionName(“重新命名操作方法”)]特性去重新命名操作方法.
[ActionName("NewActionName")]public ActionResult RenameAction(){ return Content("利用特性換個馬甲");}
2.操作方法的傳回值類型的種類
目前ASP.NET MVC3預設提供了11種ActionResult的實現
在System.Web.Mvc命名空間
ActionResult
ContentResult
EmptyResult
FileResult
HttpStatusCodeResult
HttpNotFoundResult
HttpUnauthorizedResult
JavaScriptResult
JsonResult
RedirectResult
RedirectToRouteResult
ViewResultBase
PartialViewResult
ViewResult
程式碼範例:
using System.Web.Mvc;namespace MvcApplication1.Controllers{ public class ActionResultController : Controller { public ActionResult Index() { return View(); } public ActionResult ContentResult() { return Content("Hi, 我是ContentResult結果"); } public ActionResult EmptyResult() { //空結果當然是空白了! //至於你信不信, 我反正信了 return new EmptyResult(); } public ActionResult FileResult() { var imgPath = Server.MapPath("~/demo.jpg"); return File(imgPath, "application/x-jpg", "demo.jpg"); } public ActionResult HttpNotFoundResult() { return HttpNotFound("Page Not Found"); } public ActionResult HttpUnauthorizedResult() { //未驗證時,跳轉到Logon return new HttpUnauthorizedResult(); } public ActionResult JavaScriptResult() { string js = "alert(\"Hi, I'm JavaScript.\");"; return JavaScript(js); } public ActionResult JsonResult() { var jsonObj = new { Id = 1, Name = "小銘", Sex = "男", Like = "足球" }; return Json(jsonObj, JsonRequestBehavior.AllowGet); } public ActionResult RedirectResult() { return Redirect("~/demo.jpg"); } public ActionResult RedirectToRouteResult() { return RedirectToRoute(new { controller = "Hello", action = "" }); } public ActionResult ViewResult() { return View(); } public ActionResult PartialViewResult() { return PartialView(); } //禁止直接存取的ChildAction [ChildActionOnly] public ActionResult ChildAction() { return PartialView(); } //正確使用ChildAction public ActionResult UsingChildAction() { return View(); } }}
請注意,個別的操作方法結果在執行時,他們返回的HTTP狀態代碼及ContentType有差別的.~另外如果要知道ContentType到底有多少種設定可參考
3.操作方法的參數
在本小節,我僅僅示範如何使URL參數映射到操作方法的參數,對於更複雜的用法,我將會留到 模型 的章節去講解.
首先我們需要先添加一個新的路由映射,然後在設定3個預留位置參數,它們分別是p1, p2, p3.然後將p1約束為僅字母與數位組合,p2約束為僅數字,p3沒有添加約束.
routes.MapRoute( "UsingParams", "p/{p1}/{p2}/{p3}", new { controller = "Home", action = "UsingParams" }, new { p1 = "[a-z0-9]+", p2 = @"\d+" });
在添加一個Home控制器的操作方法
public ActionResult UsingParams(string p1, int? p2, string p3){ string output = string.Empty; output += "p1 = " + (p1 ?? "null"); output += "<br />p2 = " + (p2.HasValue p2.Value.ToString() : "沒有值"); output += "<br />p3 = " + (p3 ?? "null"); return Content(output);}
運行效果
這裡在弄一個仿YouKu的URL路由設定
路由設定
routes.MapRoute( "YouKu_Show", "v_{action}/id_{id}.html", new { controller = "YouKu" }, new { id = "[a-z0-9]{13}" }, new string[] { "MvcApplication1.YouKu" });routes.MapRoute( "YouKu_PlayList", "v_{action}/{id}.html", new { controller = "YouKu" }, new { id = "[a-z0-9]{12}" }, new string[] { "MvcApplication1.YouKu" });
詳細代碼文末會放出.
III:視圖
1.視圖的文法在很早的時候我已經寫過一篇文章了.在此就略過不提.
2.視圖與控制器之間如何進行資料互動
在前面的接觸當中,我們已經對控制器和視圖有一定的瞭解了.接著,我們將要瞭解他們之間的幾種常用的資料互動方式.注意:ASP.NET MVC不存在IsPostBack.如果你需要把WebForm和MVC相結合.那麼很抱歉,我個人非常反對這種方式.因為選擇MVC的主要原因就是不希望再與runat=server打交道(當然你用ASP.NET開發而不去runat=server的話,是可以實現的).另一點MVC也方便測試.~在過去,如果你要對ASP.NET進行測試,我們可以設想一下,對每個需要測試的runat=server的伺服器控制項去設定一個預設值的話,由於屬性繁多,複雜程度已經可想而知了.另外從根源上並不能保證都能發現所有問題.~或許我的這個測試ASP.NET的猜想根本不成立.而測試的時候往往還需要每Builder一次,然後對需要測試的頁面逐個測試檢查什麼按鈕之類的..OK,這些傷心事就不在提了.下面介紹下MVC下的資料互動有那幾種方式.
2.1 ASP.NET MVC不在有IsPostBack,如何?處理GET,POST?
首先我帖出一段簡單的代碼去為你展示ASP.NET MVC3下處理GET, POST的方式
//預設是處理Get請求,當然你也可以顯式添加[HttpGet]public ActionResult UsingViewBag(){ return View();}//顯式將操作方法設定處理Post請求[HttpPost]public ActionResult UsingViewBag(string input){ if (string.IsNullOrWhiteSpace(input)) { ViewBag.Msg = inputBlank; } else { ViewBag.Msg = "你輸入了: " + input; } return View();}
在這裡你會發現在ASP.NET MVC下是用[Http*]或[AcceptVerbs(HttpVerbs.*)]特性去實作類別似WebForm下的IsPostBack.
2.2 ASP.NET MVC3的資料互動方式種類
A:ASP.NET原生的Request,Response.
System.Web.Mvc.Controller的成員:HttpContext, Request, Response, Session, User都跟WebForm下的類似.
Request.QueryString,Request.Form,Request.Cookies,RouteData.Values等.
B:ASP.NET MVC3內建的ViewData,ViewBag,TempData
using System.Web.Mvc;namespace MvcApplication1.Controllers{ public class ParamsController : Controller { string inputBlank = "你輸入了空白"; public ActionResult Index() { return View(); } //預設是處理Get請求,當然你也可以顯式添加 [HttpGet] public ActionResult UsingViewBag() { return View(); } //顯式將操作方法設定處理Post請求 [HttpPost] public ActionResult UsingViewBag(string input) { if (string.IsNullOrWhiteSpace(input)) { ViewBag.Msg = inputBlank; } else { ViewBag.Msg = "你輸入了: " + input; } return View(); } public ActionResult UsingViewData() { return View(); } [HttpPost] public ActionResult UsingViewData(string input) { if (string.IsNullOrWhiteSpace(input)) { ViewData["msg"] = inputBlank; } else { ViewData["msg"] = "你輸入了: " + input; } return View(); } public ActionResult UsingTempData() { return View(); } [HttpPost] public ActionResult UsingTempData(string input) { if (string.IsNullOrWhiteSpace(input)) { TempData["msg"] = inputBlank; } else { TempData["msg"] = "你輸入了: " + input; } return View(); } }}
更詳細的討論,或許得另寫一遍文章了.下一篇寫Model,另外關於@Html的擴充方法,我打算另外寫一篇去介紹.
IV:原始碼下載
下載原始碼
End….Thanks!