ASP.NET MVC Controllers and Actions


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就會瀏覽器機會顯示:

 

本文源碼

系列文章導航


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM