ASP.NET MVC Controllers and Actions
MVC應用程序里的URL請求是通過控制器Controller處理的,不管是請求視圖頁面的GET請求,還是傳遞數據到服務端處理的Post請求都是通過Controller來處理的,先看一個簡單的Controlller:
public class DerivedController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Hello from the DerivedController Index method"; //動態數據
return View("MyView"); //指定返回的View
}
}
是個DerivedController,那么對應處理的URL就是這樣的:localhost:1042/Derived/Index,並且Index這個Action指定了返回的視圖是MyView,而不是同名的Index視圖,那么就需要新建一個視圖MyView。在Index這個Action方法內右鍵 - 添加視圖 - MyView,或者在解決方案的Views目錄下新建一個Derived目錄,再右鍵 - 新建視圖 - MyView:
@{
ViewBag.Title = "MyView";
}
<h2>
MyView</h2>
Message: @ViewBag.Message
直接Ctrl+F5運行程序瀏覽器定位到的url是:localhost:1042,看看路由的定義:
routes.MapRoute(
"Default", // 路由名稱
"{controller}/{action}/{id}", // 帶有參數的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值
);
注意路由的最后一行:new { controller = "Home", action = "Index", id = UrlParameter.Optional }
都給默認值了,那么URL:localhost:1042 其實就是:localhost:1042/Home/Index id是可選參數。
localhost:1042/Home/Index這個Url找的Controller自然是HomeController,Index對應的是HomeController下的Index這個Action,顯然沒有HoomeController,自然會報404錯。
解決方法:
1.把路由的默認值修改成:
new { controller = "Derived", action = "Index", id = UrlParameter.Optional }
2.在瀏覽器的url欄里手動輸入:localhost:1042/Derived/index
可以通過上下文對象Context取一些參數:
string userName = User.Identity.Name; string serverName = Server.MachineName; string clientIP = Request.UserHostAddress; DateTime dateStamp = HttpContext.Timestamp;
跟普通的WebForm里一樣,可以通過Request.Form接收傳遞過來的參數:
string oldProductName = Request.Form["OldName"]; string newProductName = Request.Form["NewName"];
取URL里/路由的參數:
string city = RouteData.Values["city"].ToString();
給Controller傳參:
public ActionResult ShowWeatherForecast(string city, DateTime forDate)
{
ViewBag.City = city;
ViewBag.ForDate = forDate;
return View();
}
對應的a標簽是這樣的:
@Html.ActionLink("查看天氣(傳參)", "ShowWeatherForecast", new { city = "北京", forDate = @DateTime.Now })
再添加對應的視圖:
@{
Layout = null;
}
要查詢的是:@ViewBag.City 的天氣,查詢的時間是:@ViewBag.ForDate
運行下程序ShowWeatherForecast視圖就顯示了:
要查詢的是:北京 的天氣,查詢的時間是:2013/11/25 21:08:04
當然也可以不傳參但是提供默認值:
@Html.ActionLink("查看天氣(默認值) ", "ShowWeatherForecast", new { forDate = @DateTime.Now })
沒有傳city,看Controller:
public ActionResult ShowWeatherForecast(DateTime forDate, string city = "合肥")
{
ViewBag.City = city;
ViewBag.ForDate = forDate;
return View();
}
視圖顯示:
要查詢的是:合肥 的天氣,查詢的時間是:2013/11/25 21:16:35
默認值已經起作用了。
控制器里獲取路由數據:
public string Index()
{
string controller = (string)RouteData.Values["controller"];
string action = (string)RouteData.Values["action"];
return string.Format("Controller: {0}, Action: {1}", controller, action);
}
自然瀏覽器就會顯示:Controller: Derived, Action: index
Action里實現跳轉:
public void Index()
{
Response.Redirect("/Derived/ShowWeatherForecast");
}
使用Response.Redirect實現跳轉還比較偏WebForm化,MVC里更應該這么跳轉:
public ActionResult Index()
{
return new RedirectResult("/Derived/ShowWeatherForecast");
}
之前都是類似的Action都是Return的View這里卻Return的卻是RedirectResult,這就得看方法的返回值了,方法的返回值是ActionResult,並不僅僅是ViewResult,可以理解為ActionResult是ViewResult和RedirectResult等等的基類。
這里甚至可以直接返回視圖文件的物理路徑:
return View("~/Views/Derived/ShowWeatherForecast.cshtml");
常用的Action返回值類型有:


跳轉到別的Action:
public RedirectToRouteResult Redirect() {
return RedirectToAction("Index");
}
上面的方法是跳轉到當前Controller下的另外一個Action,如果要跳轉到別的Controller里的Action:
return RedirectToAction("Index", "MyController");
返回普通的Text數據:
public ContentResult Index() {
string message = "This is plain text";
return Content(message, "text/plain", Encoding.Default);
}
返回XML格式的數據:
public ContentResult XMLData() {
StoryLink[] stories = GetAllStories();
XElement data = new XElement("StoryList", stories.Select(e => {
return new XElement("Story",
new XAttribute("title", e.Title),
new XAttribute("description", e.Description),
new XAttribute("link", e.Url));
}));
return Content(data.ToString(), "text/xml");
}
返回JSON格式的數據(常用):
[HttpPost]
public JsonResult JsonData() {
StoryLink[] stories = GetAllStories();
return Json(stories);
}
文件下載:
public FileResult AnnualReport() {
string filename = @"c:\AnnualReport.pdf";
string contentType = "application/pdf";
string downloadName = "AnnualReport2011.pdf";
return File(filename, contentType, downloadName);
}
觸發這個Action就會返回一個文件下載提示:

返回HTTP狀態碼:
//404找不到文件
public HttpStatusCodeResult StatusCode() {
return new HttpStatusCodeResult(404, "URL cannot be serviced");
}
//404找不到文件
public HttpStatusCodeResult StatusCode() {
return HttpNotFound();
}
//401未授權
public HttpStatusCodeResult StatusCode() {
return new HttpUnauthorizedResult();
}
返回RSS訂閱內容:
public RssActionResult RSS() {
StoryLink[] stories = GetAllStories();
return new RssActionResult<StoryLink>("My Stories", stories, e => {
return new XElement("item",
new XAttribute("title", e.Title),
new XAttribute("description", e.Description),
new XAttribute("link", e.Url));
});
}
觸發這個Action就會瀏覽器機會顯示:


