一.前言
許久之后終於可以繼續我的ASP.NET MVC連載了,之前我們全面的講述了路由相關的知識,下面我們將開始控制器和動作的講解。
二.正文
1.IController的使用
這個接口可能很多人都沒有使用過,但是我們常用的Controller類實現了這個接口,而且只要實現這個接口就可以作為一個控制器,當然很多的內部的處理就要我們自己去做了。
下面我利用IController實現根據路由參數調用不同的方法:
1 public class HomeController : IController 2 { 3 public String Index() 4 { 5 return "<h1>Index</h1>"; 6 } 7 8 public String Show() 9 { 10 return "<h1>Show</h1>"; 11 } 12 13 public String Home() 14 { 15 return "<h1>Home</h1>"; 16 } 17 18 public void Execute(System.Web.Routing.RequestContext requestContext) 19 { 20 string action = requestContext.RouteData.Values["action"].ToString(); 21 Type t = typeof(HomeController); 22 MethodInfo mi = t.GetMethod(action, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 23 if (mi == null) 24 { 25 requestContext.HttpContext.Response.Write("<h1>404</h1>"); 26 } 27 else 28 { 29 string s = mi.Invoke(this, null).ToString(); 30 requestContext.HttpContext.Response.Write(s); 31 } 32 } 33 }
首先我們實現IController接口的Execute方法,然后在外面定義幾個我們需要調用的方法,然后在Execute方法中獲取action的參數,並通過反射技術獲取對應的方法,如果能夠獲取到該方法則調用該方法並返回,否則返回404。
上面僅僅只是簡單的列子,而且大多數時候我們並不需要實現IControler接口。
2.成熟的Controller
前面我們可以發現如果我們利用IController去實現控制器會非常的麻煩,但是實際上我們最終都是使用的是Controller類,
它已經實現了很多功能,這樣我們就可以關注於功能而不是底層的實現。有過ASP.NET開發的人一定知道,很多數據都是使
用Request.QueryString,RouteData來獲取的。
但是在ASP.NET MVC中可以更簡便的獲取,比如下面的代碼:
1 public class UserController : Controller 2 { 3 4 public ActionResult Index(string path) 5 { 6 ViewBag.Path1 = path; 7 return View(); 8 } 9 10 }
上面的代碼僅僅只是簡單的將傳入的path屬性存到視圖包中以便頁面輸出。
(首先我們還要新建對應的視圖頁面,頁面的代碼如下)
1 <h2>@ViewBag.Path1</h2> 2 @using (Html.BeginForm()) 3 { 4 @Html.Editor("path") 5 <input type="submit" value="submit" /> 6 }
下面我們通過這個路徑訪問頁面:http://localhost:1201/User/Index?path=12
那么最終的頁面就會如下所示:
我們可以看到uri中存在了path屬性的值所以后台的path就是12,所以頁面上輸出是12,細心的人會發覺input里面顯示的值也會跟着uri中path變化。
上面我們僅僅是通過uri改變呢,下面是通過form表單來傳遞path的值,我們在input中輸入一個值,然后點擊submit,我們可以看到如下的結果:
這里我們可以看到當我們的輸入框的值是什么,最后頁面輸出的值也是這個輸入的值。
3.動作結果
無論控制器如何的強大不能生成用戶希望的頁面,一樣也會毫無用武之地。下面我們就是要學習幾種動作結果:
A.View
這個動作結果,很多人都不會陌生,因為一創建控制器之后都會有一個默認的Index動作其中就是返回View,但是這里你要知道如果直接返回View那么對應的視圖文件會按照Views/控制器名/動作名.cshtml去查找,
當然如果找不到還會對其他公共頁面進行搜索,但是我們還可以自行指定:
首先我們在Views/User/下新建一個SubIndex.cshtml視圖,然后修改UserController中的Index方法代碼:
1 public ActionResult Index() 2 { 3 return View("SubIndex"); 4 }
這里我們可以看到我們直接將視圖的名稱作為參數傳遞給View,但這些僅僅只是控制顯示的視圖,我們最終還需要將控制器中的數據傳遞到視圖,
供視圖去顯示,這里我們可以介紹四種方式,ViewBag,ViewData,TempData,Model,下面我們用一段代碼來演示下:
1 public class UserController : Controller 2 { 3 4 public ActionResult Index() 5 { 6 ViewBag.Show = "From ViewBag"; 7 ViewData["Show"] = "From ViewBag"; 8 TempData["Show"] = "From TempData"; 9 object obj = "From Model"; 10 return View(obj); 11 } 12 13 }
這里我們在各種傳遞方式中賦值,下面就是對應的視圖:
1 <h2>@ViewBag.Show</h2> 2 <h2>@ViewData["Show"].ToString()</h2> 3 <h2>@TempData["Show"].ToString()</h2> 4 <h2>@Model</h2>
然后我們重新編譯,刷新頁面之后最終結果如下:
這里有一個要稍微介紹下,就是TempData,其實它主要是用來將數據傳遞到其他頁面的,所以他有一些特性,就是當從中讀取了數據之后就會將該數據從中清除,除非使用Peek方法讀取,那么該數據就不會被標記為刪除,
如果想刻意的將某個數據去除刪除標記,可以使用Keep方法。相關的示例這里我就不列舉了。
B.重定向
既然是開發網站,既然就會有跳轉頁面的功能,下面我們就會集中講述ASP.NET MVC中提供的重定向功能。
首先是最簡單的重定向,就是直接根據我們提供的路徑跳轉:
1 public class UserController : Controller 2 { 3 public ActionResult Index() 4 { 5 return Redirect("/Home/Index"); 6 } 7 }
這里我們可以看到Redirect中我們直接傳進了Home控制器額Index動作的路由路徑,我們打開這頁面就可以發現進行了跳轉。
如果你學會HTTP一定會知道重定向中還有一個叫永久重定向,如果我們需要使用的話,可以利用RedirectPermanent方法。
通過上面我們看到這樣需要輸入完整的路徑,當然ASP.NET MVC已經提供給我們其他的快捷的方式,比如下面的這種方式:
(我們需要在UserController中添加Show動作,同時添加對應的視圖)
1 public class UserController : Controller 2 { 3 public ActionResult Index() 4 { 5 return RedirectToAction("Show"); 6 } 7 8 public ActionResult Show() 9 { 10 return View(); 11 } 12 }
這里我們看到RedirectToAction中傳入了Show,其實這里就代表這個重定向會跳轉到Show動作中,如果需要永遠重定向可以使用RedirectToActionPermanent方法。
但有時我們需要更加靈活的方式去重定向,那么我們就可以使用下面的方式:
1 public ActionResult Index() 2 { 3 return RedirectToRoute(new { controller = "Home", action = "Index" }); 4 }
這里我們是直接通過傳遞構成該請求的控制器參數,動作參數構成最終的路由,當然我們也可以傳遞其他額外的參數到其中,
如果需要永遠重定向則使用RedirectToRoutePermanent方法。
C.其他
這里我們不每個去舉例了,下面是其他的動作結果:
Json : 將c#類轉換成json格式
Javascript : 傳遞javascript代碼
Content : 傳遞其他格式的字符數據
File : 傳遞文件流
HttpNotFoound : 404錯誤
由於最近忙於測試,所以沒有時間去寫隨筆了,這篇隨筆是利用下班在家每天寫一些最后寫出來的。當然水平上沒有前兩篇那么細膩了。