ASP.NET MVC 3教程之控制器與視圖
I:控制器和視圖的基礎(chǔ)概念
1.控制器的概念
控制器在ASP.NET MVC3當中是最終處理客戶端請求的一個實現(xiàn),他有個一硬性條件就是必須實現(xiàn)System.Web.Mvc.IController接口,而且類的命名必須要以Controller結(jié)尾,盡管按照硬性條件上來說,要自己實現(xiàn)一個接口比較糾結(jié),但幸好的是在ASP.NET MVC3內(nèi)部已經(jīng)包含了一個默認的實現(xiàn),我們只需要把類的命名設(shè)置為Controller結(jié)尾然后繼承System.Web.Mvc.Controller類,立刻就可以輕松地實現(xiàn)了IController接口了.如果你不喜歡這種默認提供的實現(xiàn)方式,而是自己去實現(xiàn)IController的話.下面的代碼可以做一個簡單的參考:
- usingSystem.Web.Mvc;
- usingSystem.Web.Routing;
- namespaceMvcApplication1.Controllers
- {
- publicclassNoDefaultController: IController
- {
- voidIController.Execute(RequestContextrequestContext)
- {
- varhttpContext = requestContext.HttpContext;
- varresponse = httpContext.Response;
- response.ContentType = "text/html; charset=utf-8";
- response.Write("自己的簡單實現(xiàn)! Hello World");
- }
- }
- }
請注意:控制器類不硬性要求放在*.Controllers命名空間中
如果是使用繼承默認的類去實現(xiàn)的話代碼如下:
- usingSystem.Web.Mvc;
- namespaceMvcApplication1
- {
- publicclassHelloController: Controller
- {
- publicActionResultIndex()
- {
- returnContent("默認的實現(xiàn)! Hello World");
- }
- }
- }
效果圖我就不發(fā)了.大家可以手動試一試.
2.視圖的概念
視圖的理解比較簡單.你可以把視圖理解為*.aspx或*.cshtml的文件.但是不是所有的aspx, cshtml文件都可以作為視圖,它們必須得屬于某一個以控制器名稱命名的文件夾當中,而且要按照約定去存放到路徑 ~/Views/{controller}/View.cshtml.
另外視圖還包含解析他的ViewEngine(視圖引擎),本文在這里不涉及這個高級話題.
我們可以看出在~/Views/{controller}/View.cshtml中的{controller}并不需要像類命名那樣以Controller結(jié)尾去做文件夾名稱.
3.工作原理圖
當然,內(nèi)部的工作原理會比這個圖復(fù)雜得多.在此也僅僅是讓大家有個了解而已!如有錯誤請指出.謝謝!
提示:MvcHandler實現(xiàn)了IHttpAsyncHandler, IHttpHandler, IRequiresSessionState這三個接口,我在Debug進去的時候發(fā)現(xiàn)都是走異步的路線.對于這個處理方式,了解的人希望可以為我解答一下!
II:控制器
1.操作方法
操作方法的含義是指在繼承了System.Web.Mvc.Controller類中所定義的返回值的類型可以兼容ActionResult的方法.
- usingSystem.Web.Mvc;
- namespaceMvcApplication1.Controllers
- {
- publicclassHomeController: Controller
- {
- ///<summary>
- ///Hi, 我是Index操作方法
- ///</summary>
- ///<returns></returns>
- publicActionResultIndex()
- {
- ViewBag.Message = "Welcome to ASP.NET MVC!";
- returnView();
- }
- ///<summary>
- ///厄, 我是About操作方法
- ///</summary>
- ///<returns></returns>
- publicActionResultAbout()
- {
- returnView();
- }
- ///<summary>
- ///可以為方法添加不是操作方法的特性
- ///</summary>
- ///<returns></returns>
- [NonAction]
- publicstringNonAction()
- {
- return"親,不好意思噢.我不是操作方法噢,請不要亂調(diào)用噢!";
- }
- }
- }
- 同時也可以使用[ActionName(“重命名操作方法”)]特性去重命名操作方法.
- [ActionName("NewActionName")]
- publicActionResultRenameAction()
- {
- returnContent("利用特性換個馬甲");
- }
2.操作方法的返回值類型的種類
目前ASP.NET MVC3默認提供了11種ActionResult的實現(xiàn)
在System.Web.Mvc命名空間
ActionResult
ContentResult
EmptyResult
FileResult
HttpStatusCodeResult
HttpNotFoundResult
HttpUnauthorizedResult
JavaScriptResult
JsonResult
RedirectResult
RedirectToRouteResult
ViewResultBase
PartialViewResult
ViewResult
代碼示例:
- usingSystem.Web.Mvc;
- namespaceMvcApplication1.Controllers
- {
- publicclassActionResultController: Controller
- {
- publicActionResultIndex()
- {
- returnView();
- }
- publicActionResultContentResult()
- {
- returnContent("Hi, 我是ContentResult結(jié)果");
- }
- publicActionResultEmptyResult()
- {
- //空結(jié)果當然是空白了!
- //至于你信不信, 我反正信了
- returnnewEmptyResult();
- }
- publicActionResultFileResult()
- {
- varimgPath = Server.MapPath("~/demo.jpg");
- returnFile(imgPath, "application/x-jpg", "demo.jpg");
- }
- publicActionResultHttpNotFoundResult()
- {
- returnHttpNotFound("Page Not Found");
- }
- publicActionResultHttpUnauthorizedResult()
- {
- //未驗證時,跳轉(zhuǎn)到Logon
- returnnewHttpUnauthorizedResult();
- }
- publicActionResultJavaScriptResult()
- {
- stringjs = "alert(\"Hi, I'm JavaScript.\");";
- returnJavaScript(js);
- }
- publicActionResultJsonResult()
- {
- varjsonObj = new
- {
- Id = 1,
- Name = "小銘",
- Sex = "男",
- Like = "足球"
- };
- returnJson(jsonObj, JsonRequestBehavior.AllowGet);
- }
- publicActionResultRedirectResult()
- {
- returnRedirect("~/demo.jpg");
- }
- publicActionResultRedirectToRouteResult()
- {
- returnRedirectToRoute(new{
- controller = "Hello", action = ""
- });
- }
- publicActionResultViewResult()
- {
- returnView();
- }
- publicActionResultPartialViewResult()
- {
- returnPartialView();
- }
- //禁止直接訪問的ChildAction
- [ChildActionOnly]
- publicActionResultChildAction()
- {
- returnPartialView();
- }
- //正確使用ChildAction
- publicActionResultUsingChildAction()
- {
- returnView();
- }
- }
- }
請注意,個別的操作方法結(jié)果在執(zhí)行時,他們返回的HTTP狀態(tài)碼及ContentType有差別的.~另外如果要知道ContentType到底有多少種設(shè)置可參考
3.操作方法的參數(shù)
在本小節(jié),我僅僅演示如何使URL參數(shù)映射到操作方法的參數(shù),對于更復(fù)雜的用法,我將會留到 模型 的章節(jié)去講解.
首先我們需要先添加一個新的路由映射,然后在設(shè)置3個占位符參數(shù),它們分別是p1, p2, p3.然后將p1約束為僅字母與數(shù)字的組合,p2約束為僅數(shù)字,p3沒有添加約束.
- routes.MapRoute(
- "UsingParams",
- "p/{p1}/{p2}/{p3}",
- new{
- controller = "Home",
- action = "UsingParams"
- },
- new{ p1 = "[a-z0-9]+", p2 = @"d+"}
- );
在添加一個Home控制器的操作方法
- publicActionResultUsingParams(stringp1, intp2, stringp3)
- {
- stringoutput = string.Empty;
- output += "p1 = "+ (p1 ?? "null");
- output += "<br />p2 = "
- + (p2.HasValue p2.Value.ToString() : "沒有值");
- output += "<br />p3 = "+ (p3 ?? "null");
- returnContent(output);
- }
運行效果
這里在弄一個仿YouKu的URL路由設(shè)置
路由設(shè)置
- routes.MapRoute(
- "YouKu_Show",
- "v_{action}/id_{id}.html",
- new{ controller = "YouKu"},
- new{ id = "[a-z0-9]{13}"},
- newstring[] { "MvcApplication1.YouKu"}
- );
- routes.MapRoute(
- "YouKu_PlayList",
- "v_{action}/{id}.html",
- new{ controller = "YouKu"},
- new{ id = "[a-z0-9]{12}"},
- newstring[] { "MvcApplication1.YouKu"}
- );
詳細代碼文末會放出.
III:視圖
1.視圖的語法在很早的時候我已經(jīng)寫過一篇文章了.在此就略過不提.
2.視圖與控制器之間如何進行數(shù)據(jù)交互
在前面的接觸當中,我們已經(jīng)對控制器和視圖有一定的了解了.接著,我們將要了解他們之間的幾種常用的數(shù)據(jù)交互方式.注意:ASP.NET MVC不存在IsPostBack.如果你需要把WebForm和MVC相結(jié)合.那么很抱歉,我個人非常反對這種方式.因為選擇MVC的主要原因就是不希望再與runat=server打交道(當然你用ASP.NET開發(fā)而不去runat=server的話,是可以實現(xiàn)的).另一點MVC也方便測試.~在過去,如果你要對ASP.NET進行測試,我們可以設(shè)想一下,對每個需要測試的runat=server的服務(wù)器控件去設(shè)置一個預(yù)設(shè)值的話,由于屬性繁多,復(fù)雜程度已經(jīng)可想而知了.另外從根源上并不能保證都能發(fā)現(xiàn)所有問題.~或許我的這個測試ASP.NET的猜想根本不成立.而測試的時候往往還需要每Builder一次,然后對需要測試的頁面逐個測試檢查什么按鈕之類的..OK,這些傷心事就不在提了.下面介紹下MVC下的數(shù)據(jù)交互有那幾種方式.
2.1 ASP.NET MVC不在有IsPostBack,如何實現(xiàn)處理GET,POST?
首先我帖出一段簡單的代碼去為你展示ASP.NET MVC3下處理GET, POST的方式
- //默認是處理Get請求,當然你也可以顯式添加
- [HttpGet]
- publicActionResultUsingViewBag()
- {
- returnView();
- }
- //顯式將操作方法設(shè)置處理Post請求
- [HttpPost]
- publicActionResultUsingViewBag(stringinput)
- {
- if(string.IsNullOrWhiteSpace(input))
- {
- ViewBag.Msg = inputBlank;
- }
- else
- {
- ViewBag.Msg = "你輸入了: "+ input;
- }
- returnView();
- }
在這里你會發(fā)現(xiàn)在ASP.NET MVC下是用[Http*]或[AcceptVerbs(HttpVerbs.*)]特性去實現(xiàn)類似WebForm下的IsPostBack.
2.2 ASP.NET MVC3的數(shù)據(jù)交互方式種類
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
- usingSystem.Web.Mvc;
- namespaceMvcApplication1.Controllers
- {
- publicclassParamsController: Controller
- {
- stringinputBlank = "你輸入了空白";
- publicActionResultIndex()
- {
- returnView();
- }
- //默認是處理Get請求,當然你也可以顯式添加
- [HttpGet]
- publicActionResultUsingViewBag()
- {
- returnView();
- }
- //顯式將操作方法設(shè)置處理Post請求
- [HttpPost]
- publicActionResultUsingViewBag(stringinput)
- {
- if(string.IsNullOrWhiteSpace(input))
- {
- ViewBag.Msg = inputBlank;
- }
- else
- {
- ViewBag.Msg = "你輸入了: "+ input;
- }
- returnView();
- }
- publicActionResultUsingViewData()
- {
- returnView();
- }
- [HttpPost]
- publicActionResultUsingViewData(stringinput)
- {
- if(string.IsNullOrWhiteSpace(input))
- {
- ViewData["msg"] = inputBlank;
- }
- else
- {
- ViewData["msg"] = "你輸入了: "+ input;
- }
- returnView();
- }
- publicActionResultUsingTempData()
- {
- returnView();
- }
- [HttpPost]
- publicActionResultUsingTempData(stringinput)
- {
- if(string.IsNullOrWhiteSpace(input))
- {
- TempData["msg"] = inputBlank;
- }
- else
- {
- TempData["msg"] = "你輸入了: "+ input;
- }
- returnView();
- }
- } }
更詳細的討論,或許得另寫一遍文章了.下一篇寫Model,另外關(guān)于@Html的擴展方法,我打算另外寫一篇去介紹.
IV:源代碼下載
原文:http://www.cnblogs.com/highend/archive/2011/08/04/aspnet_mvc3_controller_and_view.html
【編輯推薦】
- 詳解ASP.NET MVC 3新的Layout布局系統(tǒng)
- ASP.NET MVC中很酷的jQuery驗證插件
- ASP.NET MVC 3新特性全解析
- ASP.NET MVC 3讓你瘋狂的五大理由
- 詳解ASP.NET MVC 3 beta新特性