1. Controller
Controller是ASP.NET MVC的核心,負責處理瀏覽器請求,並作出響應。Cotroller本身是一個類(Class),該類有多個方法(Method)。在這些方法中,只要是公開方法,該方法將被視為一個動作(Action);只要有動作存在,就可以通過該動作方法接收網頁請求並決定應響應的視圖。
1.1 Controller的基本要求:
◊ Controller必須是公共(Public)類;
◊ Controller的名稱必須以“Controller”結尾;
◊ 必須繼承ASP.NET MVC的Controller類,或繼承實現IController接口的自定義類,或自身實現IController接口;
◊ 所有方法必須為Public方法。該方法可以沒有參數,也可以有多個參數。
2. Action名稱選擇器
當通過ActionInvoker選取Controller中的公共方法時,默認會用Reflection方式取得Controller中具有相同名稱的方法。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { /// <summary> /// http://localhost/Home/Index /// </summary> public ActionResult Index() { return View(); } } }
可以通過在Action上使用ActionName屬性(Attribute)來指定Action,這就是動作名稱選擇器(Action Name Selector)。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { /// <summary> /// http://localhost/Home/Default /// </summary> [ActionName("Default")] public ActionResult Index() { return View(); } } }
3. 動作方法選擇器
在通過ActionInvoker選取Controller中的公共方法是,ASP.NET MVC還提供了一個特性,動作方法選擇器(Action Method Selector),以幫助ActionInvoker選擇適當的Action。
3.1 NonAction屬性
若將NonAction屬性應用在Controller中的Action方法上,即使該Action方法是公共方法,也會告知ActionInvoker不要選取這個Action來執行。這個屬性主要用來保護Controller中的特定公共方法不會發布到Web上。或是當功能尚未開發完成就要進行部署時,若暫時不想將此方法刪除,也可以使用這個屬性。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { [NonAction] public ActionResult Index() { return View(); } } }
將Action方法的“public”改成“private”,也可以達到同樣的目的。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { private ActionResult Index() { return View(); } } }
3.2 HttpGet屬性、HttpPost屬性、HttpDelete屬性和HttpInput屬性
HttpGet、HttpPost、HttpDelete、HttpInput屬性是動作方法選取器的一部分,這些屬性常用在需要接收窗口數據的時候。如:創建兩個同名的Action,一個應用[HttpGet]屬性來顯示窗口HTML,另一個應用[HttpPost]屬性來接收窗口發送的值。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Libing.Portal.Web.Models; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpGet] public ActionResult Create() { return View(); } public ActionResult Create(Product product) { //UpdateModel(product); return RedirectToAction("Index"); } } }
4. ActionResult類
ActionResult類是Action執行的結果,但ActionResult中並不包含執行結果,而是包含執行響應時所需要的信息。當Action返回ActionResult類之后,會由ASP.NET MVC執行。
ASP.NET MVC定義的ActionResult如下表所示:
類 | Controller輔助方法 | 用途 |
---|---|---|
ContentResult | Content | 返回一段用戶自定義的文字內容 |
EmptyResult | 不返回任何數據,即不響應任何數據 | |
JsonResult | Json | 將數據序列轉化成JSON格式返回 |
RedirectResult | Redirect | 重定向到指定的URL |
RedirectToRouteResult | RedirectToAction、RedirectToRoute | 重定向到Action或Route |
ViewResult | View | 使用IViewInstance接口和IViewEngine接口,實際輸出的數據是IViewEngine接口和View |
PartialViewResult | PartialView | 與ViewResult類相似,返回的是“部分顯示” |
FileResult | File | 以二進制串流的方式返回一個文件數據 |
JavaScriptResult | JavaScript | 返回JavaScript指令碼 |
以上的動作結果都繼承自ActionResult基類。
4.1 ViewResult
ViewResult類是在ASP.NET MVC中最常用的ActionResult類,用於返回一個標准的視圖。通過Controller輔助方法,可以定義輸出的View名稱。
4.1.1 返回默認的頁面
返回的默認頁面與Action的名稱相同
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } } }
public ViewResult Index() { return View(); }
4.1.2 指定頁面名稱的響應
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Index() { return View("Default"); } } }
4.1.3 指定的頁面不存在
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Index() { return View("NotExists"); } } }
當在Views目錄下找不到頁面時,出現下面的提示信息。
4.2 PartialViewResult
PartialViewResult與ViewResult非常相似,通過用在前端為Ajax應用程序的情況下,並可以通過Ajax來取得網頁中的部分內容。
public ActionResult About() { return PartialView(); }
4.3 EmptyResult
有一些Action在執行后其實不需要返回任何數據,例如一個頁面執行完后直接轉到其他頁面的情況。EmptyResult不會執行任何響應客戶端的程序,所以也不會返回任何數據。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Empty() { return new EmptyResult(); } } }
或
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public void Empty() { return; } } }
public EmptyResult Index() { return new EmptyResult(); }
使用EmptyResult與Response.RedirectPermanent()進行HTTP301跳轉
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public void Redirect() { Response.RedirectPermanent("/Home/Index"); } } }
public RedirectResult About() { return Redirect("/Home/Index"); }
4.4 ContentResult
ContentResult類可以響應文字內容的結果。可以讓ContentResult類響應任意指定文字內容、Content-Type和文字編碼(Encoding)。
示例響應一段XML文字,並設定響應的Content-Type為text/xml,文本編碼格式為Encoding.UTF8.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Content() { return Content("<root><text>123</text></root>", "text/xml", System.Text.Encoding.UTF8); } } }
響應HTML字符串
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public ActionResult Content() { string strHTML = "<h1>123</h1>"; return Content(strHTML); } } }
ASP.NET MVC會進行判斷,只要Action返回的不是ActionResult類,就會將返回的類轉換成字符串輸出。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Libing.Portal.Web.Controllers { public class HomeController : Controller { public string Content() { string strHTML = "<h1>123</h1>"; return strHTML; } } }
6.5 FileResult
FileResult類可以響應任意的文件內容,包括二進制格式的數據,可以輸入byte[]、文件路徑、Stream數據、Content-Type、下載文件名等參數並將其返回客戶端。
FileResult是一個抽象類,在ASP.NET MVC中實現FileResult類的子類包括:
◊ FilePathResult:響應一個實體文件;
◊ FileContentResult:響應一個byte[]的內容;
◊ FileStreamResult:響應一個Stream數據。
示例:FilePathResult
public ActionResult Download() { return File(Server.MapPath("~/Content/Logo.png"), "image/png"); }
示例:FileContentResult
public ActionResult Download() { FileStream fs = new FileStream(Server.MapPath("~/Content/Logo.png"), FileMode.Open, FileAccess.Read); byte[] fileContent = new byte[Convert.ToInt32(fs.Length)]; fs.Read(fileContent, 0, Convert.ToInt32(fs.Length)); return File(fileContent, "image/png"); }
示例:FileStreamResult
public ActionResult Download() { FileStream fs = new FileStream(Server.MapPath("~/Content/Logo.png"), FileMode.Open, FileAccess.Read); return File(fs, "image/png"); }
示例:pdf文件
public ActionResult Download() { FileStream fs = new FileStream(Server.MapPath("~/Content/Report.pdf"), FileMode.Open, FileAccess.Read); byte[] fileContent = new byte[Convert.ToInt32(fs.Length)]; fs.Read(fileContent, 0, Convert.ToInt32(fs.Length)); return File(fileContent, "application/pdf", "Report.pdf"); }
示例:中文名稱文件
public ActionResult Download() { FileStream fs = new FileStream(Server.MapPath("~/Content/Report.txt"), FileMode.Open, FileAccess.Read); byte[] fileContent = new byte[Convert.ToInt32(fs.Length)]; fs.Read(fileContent, 0, Convert.ToInt32(fs.Length)); return File(fileContent, "text/plain", Server.UrlPathEncode("報表.txt")); }
6.6 JavaScriptResult
JavaScriptResult類的用途是將JavaScript代碼響應給瀏覽器。通過Ajax利用JavaScriptResult類來響應當前的JavaScript程序代碼並將其提交到瀏覽器動態執行。
JavaScriptResult類的功能與ContentResult類主要差別在於JavaScriptResult類的默認Content-Type為application/x-javascript。
public ActionResult RunJavaScript() { return JavaScript("alert('運行JavaScript')"); }
@Ajax.ActionLink("測試JavaScript", "RunJavaScript", new AjaxOptions())
6.7 JsonResult
JSON(JavaScript Object Notation)是Web實現Ajax應用程序時經常使用的一種數據傳輸格式,JsonResult可以自動將任意對象的數據序列轉換成JSON格式返回。JsonResult默認的Content-Type是application/json。
JsonResult使用JavaScriptSerializer完成JSON序列化,如果對象無法序列化,轉換過程也會發生意外。為了避免JSON Hijacking攻擊,ASP.NET MVC基於安全考慮,設置在默認情況下,任何以JsonResult類返回的請求都不允許GET方法從中獲取JSON數據。要JsonResult對HTTP GET請求進行響應,需Json()方法設置JsonRequestBehavior.AllowGet。
示例:Json()默認
public ActionResult GetList() { List<Product> products = new List<Product>(); products.Add(new Product { ProductID = 1, ProductName = "ASP.NET MVC" }); return Json(new { root = products, totalProperty = products.Count }); }
<script type="text/javascript"> $(function () { $.post("@Url.Action("GetList","Home")", function (data) { console.log(data.totalProperty); }, "json" ); }); </script>
示例:Json() AllowGet
public ActionResult GetList() { List<Product> products = new List<Product>(); products.Add(new Product { ProductID = 1, ProductName = "ASP.NET MVC" }); return Json(new { root = products, totalProperty = products.Count }, JsonRequestBehavior.AllowGet); }
<script type="text/javascript"> $(function () { $.get("@Url.Action("GetList","Home")", function (data) { console.log(data.totalProperty); }, "json" ); }); </script>
6.8 RedirectResult
RedirectResult主要用於執行指向其他頁面的重定向。
Redirect()方法定義:
protected internal virtual RedirectResult Redirect(string url);
示例:
public ActionResult Redirect() { return Redirect("/Home/Index"); }
6.9 RedirectToRoute
Controller類中有兩個與RedirectToRoute類有關的輔助方法:RedirectToAction()和RedirectToRoute()。
6.9.1 RedirectToAction
1>. 原型定義
protected internal RedirectToRouteResult RedirectToAction(string actionName);
protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName);
protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues);
protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);
2>. 示例
public ActionResult About() { return RedirectToAction("Index"); }
return RedirectToAction("Index", "Home");
return RedirectToAction("List", "Home", new { page = 2 });
return RedirectToAction("Details", new { id = product.ProductID });
6.9.2 RedirectToRoute
1>. 原型定義
protected internal RedirectToRouteResult RedirectToRoute(object routeValues);
protected internal RedirectToRouteResult RedirectToRoute(string routeName);
protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues);
2>. 示例
public ActionResult About() { return RedirectToRoute(new { action = "Index" }); }
return RedirectToRoute(new { controller = "Home", action = "Index" });
return RedirectToRoute(new { controller = "Home", action = "Index", page = 2 });