重定向到文本URL(Redirecting to a Literal URL)
最基本的重定向浏覽器方式就是調用Redirect方法,該方法會傳回一個RedirectResult類的執行個體。
例如:public RedirectResult Redirect() {return RedirectPermanent("/Example/Index"); }當然我們可以根據自己的喜好來選擇Redirect方法的重載,可以添加一個bool類型的參數指定是否永久重定向(不指定則是暫時重定向)
進行單元測試:

View Code
重定向到路由系統URL(Redirecting to a Routing System URL)
如果我們正在重定向使用者到應用程式一個不同的部分,我們需要確定發送的URL是在URL架構裡面驗證通過的。使用文本URL重定向的問題是對路由架構的任何的改變會導緻周遊整個代碼并更新URL。為了避免這個這問題,我們可以使用路由系統RedirectToRoute方法生成驗證的URL,即建立RedirectToRouteResult的執行個體。
如下所示:

RedirectToRoute方法發起的是一個暫時重定向(temporary redirection),如果要實作永久重定向可以使用RedirectToRoutePermanent方法。兩個方法都接收一個匿名類型參數傳遞給路由系統生成一個URL。下面是單元測試:

重定向到Action方法(Redirecting to an Action Method)
使用RedirectToAction方法能夠很優雅的重定向到一個Action方法,這個方法僅僅是對RedirectToRoute方法的封裝,讓我們指定action方法的值并且controller不需要建立一個匿名類型。如public RedirectToRouteResult Redirect() {return RedirectToAction("Index"); }如果我們指定一個action方法,那麼就假定了是在目前controller裡面的額action方法。如果我們想重定向到其他的controller,我們需要提供一個controller名。像這樣:return RedirectToAction("Index", "MyController"); 當然還有其他的重載方法,讓我們能夠簡便的編碼。
注意:我們傳入的action參數或controller參數在它們被傳遞給路由系統之前是不會驗證的,是以我們要確定目标controller和action方法是存在的。
重定向會引起浏覽器送出一整個新的HTTP請求,這樣意味着我們無法通路原始請求的細節。如果我們想将資料從一個請求傳遞到下一個,可以使用TempData功能。
TempData類似與Session,不同的是TempData在被讀取以後會被标記删除,并且當請求被處理的時候被移除。這是一個針對我們想在整個重定向過程中保持短期資料的非常完美的安排。下面我們通過一個例子來驗證TempData的值隻被讀取一次:
接着添加兩個View,分别是Index和About,代碼如下:
運作程式就一目了然了,如下所示:
如果我們想讀取TempData的值但是又不讓它被删除,可以使用TempData.Peek("Date")方法。如果想在保持一次TempData裡面的值,可以使用TempData.Keep("Date").
您可以将上面的controller裡面的兩行注釋的代碼取消注釋并在Index裡面加上讀取TempData["Message"]的代碼,運作程式就明白了。
傳回文本資料(Returning Text Data)
除了HTML,我們可能需要讓我們的程式生成很多其他的基于文本的資料格式來響應請求。這些文本的格式包含:XML,JSON,CSV,一般文本。MVC架構明确對JSON格式提供了支援,對這些文本資料類型,我們使用ContentResult作為action的傳回值類型。如下所示:
public ContentResult Index()
{
string message = "This is plain text";
return Content(message, "text/plain", Encoding.Default);
}
我們通過Content方法建立ContentResult,并擷取三個參數:1.發送的文本資料;2.響應的HTTP content-type header.3.編碼格式。
我們可以忽略最後兩個參數,在MVC架構假定資料是HTML(content type為text/html)情況下,它會查詢一種浏覽器聲明支援的編碼格式。
比如,我們僅僅傳回一個文本可以這樣:return Content("This is plain text");
實際上,如果我們傳回任何一個不是ActionResult類型的對象,MVC架構會試圖序列化資料成一個字元串并作為HTML發送給浏覽器。例如:
public object Test(){return "This is plain text";},此時運作程式可以看到浏覽器顯示:This is plain text。
單元測試如下:

傳回XML資料(Returning XML Data )
從action方法傳回XML資料是非常簡單的,特别是當我們使用LINQ2XML和XDocument API從對象建立XML時。如下所示:

傳回JSON資料(Returning JSON Data)
最近幾年,在web程式中對XML的使用在慢慢減少,而是更加喜歡用JSON格式(JavaScript Object Notation)傳輸資料,JSON是一個輕量級的基于文本格式,用來描述分層資料結構的,JSON是有效的javascript代碼,這意味着被所有的主流浏覽器支援,這也是讓JSON相對于XML更加有影響更加簡便。在MVC架構裡面内置了JsonResult類,讓我們能夠序列化.net對象為json格式。通過Json方法可以建立傳回JsonResult結果類型。如:
[HttpPost]
public JsonResult JsonData() {StoryLink[] stories = GetAllStories(); return Json(stories); }生成的格式資料像這樣,如下所示:

注意:為了更加安全的緣故,JsonResult對象隻對HTTP Post請求生成一個響應,這是為了阻止資料因為第三方法跨站點請求被暴露。推薦在傳回JsonResult類型的action方法上面加上[HttpPost]作為一個提示,盡管這不是必須的,後面的章節會解釋這樣做的原因。
傳回檔案和二進制資料(Returning Files and Binary Data )
FileResult是一個抽象的基類,MVC架構自帶了三個實作的子類,如下:
1.FilePathResult:直接從伺服器發送一個檔案
2.FileContentResult:發送記憶體裡面位元組數組的内容
3.FileStreamResult:發送一個已經打開的System.IO.Stream對象的内容
我們不用擔心具體用哪一個,因為MVC提供了一個Controller.File輔助方法不同的重載版本來為我們自動建立。下面依次說明:
發送一個檔案:

執行時,會彈出一個儲存檔案的對話框。對于File方法有三個參數:filename,contentType,fileDownloadName,前面兩個是必須的。
發送位元組數組,發送Stream對象都是在File的第一個參數進行變化,是以就不在贅述了。
傳回錯誤和HTTP代碼
最後一個MVC内置的ActionResult類就是我們用來發送具體錯誤資訊和HTTP結果的代碼到用戶端。很多應用程式對這個功能不是必須使用的,因為MVC會自動建立。但是,它們能夠幫助我們更加直接的控制發送到用戶端的響應。
發送一個指定的HTTP結果代碼:使用HttpStatusCodeResult類,
如public HttpStatusCodeResult StatusCode() { return new HttpStatusCodeResult(404, "URL cannot be serviced"); }
發送一個404結果:public HttpStatusCodeResult StatusCode() {return HttpNotFound(); }
發送一個401結果:public HttpStatusCodeResult StatusCode() {return new HttpUnauthorizedResult(); }
建立一個自定義的ActionResult
内置的action result已經能夠充分滿足大多數情形和應用程式,但我們可以在特殊情況下自己定義action result。下面的部分通過生成一個RSS文檔來示範自定義action result

實際上,我們定義了兩個類,一個是RssActionResult抽象類(ActionResult的子類),另一個是從RssActionResult派生的RssActionResult<T>。我們定義兩個類是為了能夠建立傳回類型是RssActionResult的action方法。
好了,今天的筆記就到這裡,關于Controllers and Actions 章的筆記到這裡也結束了。
晚安!