請注明轉載地址:http://www.cnblogs.com/arhat
在上一章中,我們講述了ActionResult的三個子類,非別是EmptyResult,RediretResult和ContentResult。那么本章我們在講幾個ActionResult的子類。
JsonResult | 表示可以運用到AJAX程序中JSON結果 |
JavaScriptResult | 表示一個JavaScript對象 |
FileContentResult | 表示一個可以下載的、二進制內容的文件 |
FilePathResult | 表示一個可以下載的、指定路徑的文件 |
首先就是JsonResult,從名字看,我們可以猜出,這個結果和Json是相關的,返回的類型是以Json格式的,所以一般這個用於Ajax請求,當然在Ajax請求的時候要設置服務器端返回的類型是json。下面我們通過一個案例來研究這個JsonResult。在這個案例中,我們使用了Jquery。首先我們新建一個項目“Com.ArHat.Web”。並添加一個HomeController控制器,同時在Models文件夾中添加一個類M_User.cs。代碼如下:
M_User:
public class M_User { public string Name { get; set; } public int Age { get; set; } }
HomeController:
public ActionResult Index() { return View(); } public ActionResult AjaxUserInfo() { Models.M_User user = new Models.M_User() { Name="濟公活佛",Age=90}; return Json(user,JsonRequestBehavior.AllowGet); }
同時我們添加Index的視圖文件Index.cshtml,內容如下:
@{ ViewBag.Title = "JsonResult"; } <script type="text/javascript"> function AjaxSearch() { $.get("/Home/AjaxUserInfo", null, function (data) { var html = "姓名:" + data.Name + ",年齡:" + data.Age; $("#result").html(html); }, "json"); } </script> <h2>這是JsonResult實例</h2> 請輸入用戶的名字:<input type="button" value="查詢" onclick="AjaxSearch()" /> <div id="result" style="margin:10px"> </div>
我們在瀏覽器中預覽一下,當點擊查詢按鈕的時候,發現數據已經顯示到div中了。我們來分一下上面的代碼。
首先我們再視圖文件中使用了$.get來發送一個異步的get請求,請求的Action是HomeController下的AjaxUserInfo。這一點沒什么難度。主要在AjaxUserInfo這函數中,我們創建了一個對象M_User,最關鍵的一點事Controller提供的Json函數。這個函數返回的類型就是JsonResult。下面我們來看一下Json函數的定義:
protected internal JsonResult Json(object data); protected internal JsonResult Json(object data, JsonRequestBehavior behavior); protected internal JsonResult Json(object data, string contentType);
這個函數中,都必須提供參數”object data”。這個就是要把對象轉換為json數據。比如M_User對象,有屬性Name,Age.那么JsonResult就會把這個對象轉為Json對象{Name:”xxx”,Age:YY}。
其中的第二個重載函數,提供了另外一個參數JsonRequestBehavior這個參數是說明請求Json的方式,默認情況下,如果是get請求,則是不允許的,如果要使異步的get請求起作用,則必須設置JsonRequestBehavior.AllowGet。可以猜測出,JsonRequestBehavior是個枚舉類型了,還有一個枚舉值是DenyGet(阻止Get,這個是默認值)。
所以我們在AjaxUserInfo中,使用了的第二個重載。那么我們來分析一下最后的結果。我們使用firefox瀏覽器,通過firebug來看看結果。
從上面的結果,我們可以看出和我們猜測的是一樣的,JsonResult把對象自動轉換為了json數據了。
下面我們來看看JavaScriptResult。現在我挺佩服微軟的命名規則的,特別見名之意啊。從名字上看,返回的就是一個JavaScript對象。別看返回的事JavaScript對象,但是這個對象確是“純文本”的哦!
現在我們改寫一下Index函數,內容如下:
public ActionResult Index() { string js = "alert('sss')"; return JavaScript(js); }
發了什么問題呢?原來alert函數並沒有執行,而是當做純文本來輸出了,這是怎么回事呢?原因是JavascriptResult要和Ajax一起使用,而這個Ajax和我們傳統的Ajax有些不同,需要使用在Razor頁面中使用@Ajax生成的鏈接或者是表單來調用,從一定程度上可以看成是“回發”,但這種回發是純粹的Ajax。而且頁面中調用的Ajax函數必須在本Controller中定義才可以。下面我們改寫一下HomeController:
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult AjaxUserInfo() { Models.M_User user = new Models.M_User() { Name="濟公活佛",Age=90}; return Json(user,JsonRequestBehavior.AllowGet); } public ActionResult JSResult() { string js = "alert('sss')"; return JavaScript(js); } }
同時我們需要改寫_Layout.cshtml,在_Layout.cshtml中加上
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
只有加上了這個js,@Ajax才會起作用。下面我們改寫一下Index.cshtml
@{ ViewBag.Title = "JsonResult"; } <script type="text/javascript"> function AjaxSearch() { $.get("/Home/AjaxUserInfo", null, function (data) { var html = "姓名:" + data.Name + ",年齡:" + data.Age; $("#result").html(html+","); }, "json"); } </script> <h2>這是JsonResult實例</h2> 請輸入用戶的名字:<input type="button" value="查詢" onclick="AjaxSearch()" /> <div id="result" style="margin:10px"> </div> <br /> <a href="/Home/JSResult">這是JavaScriptResult——普通調用</a> <br /> <br /> @Ajax.ActionLink("這是JavaScriptResult——Ajax調用", "JSResult", new AjaxOptions())
在Index.cshtml中,我們加入了兩個超鏈接,一個是普通的,一個是@Ajax生成的超鏈接。我們在瀏覽器中預覽一下,分別點擊這兩個超鏈會發現,第一個是以另外一個頁面顯示內容,第二個是在本頁面直接執行了javascript代碼。同時我們查看一下源代碼:
發現通過@Ajax生成的標簽中多了幾個data-*的屬性,而且功能正常執行,我們會感覺比較奇怪,因為這是一種JavaScript的編寫風格(和html5相關),這種風格稱之為”Unobtrusive Javascript”。其實這種應用在Jquery EasyUI中經常用的到。需要注意的是,如果要使用@Ajax,那么在頁面中必須導入
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
而且在頁面中所調用的方法必須是在頁面所對應的Controller中。
@Ajax.ActionLink("這是JavaScriptResult——Ajax調用", "JSResult", new AjaxOptions())。
大家會發現,上面的代碼是在HomeController的Index方法所對應的視圖中,那么“JSResult”這個方法必須在HomeController中。如果,我們現在再創建一個Controller為TestController,內容如下:
public ActionResult Index()
{
return JavaScript("alert('22222')");
}
同時我們改一下Home/Index方法對應的視圖文件Index.cshtml
@Ajax.ActionLink("這是JavaScriptResult——Ajax調用", "/Test/Index", new AjaxOptions())
我們預覽一下,發現請求失敗哦。為什么呢?我們觀察一下生成的源代碼:
發現地址這么會是/Home/Test/Index呢?這一點就說明了這種Ajax方法必須是在視圖對應的Controller中聲明。所以這也就是我為什么稱它為另一種的“回發”。只不過這種“回發”是Ajax形式的。比如,我們post提交一個記錄后,需要返回一個說明,但是這個說明是cs生成的,那么就可以利用這種方法。
下面,我們來分析一下@Ajax輔助方法ActionLink(text,action, AjaxOptions)。
如果說,我們必須要調用TestController中的Index方法,怎么辦呢?我們可以使用@Ajax.ActionLink的第二個重載函數:ActionLink(text,action, new object,AjaxOptions)。
就按上面的說法,我們要調用TestController中的Index方法,則我們可以這樣寫:
@Ajax.ActionLink("這是JavaScriptResult——Ajax調用", "Index",new {controller="Test"}, new AjaxOptions())
這個方法提提供了幾個參數,第一個參數text:是要顯示的文本,action是要調用的Ajax方法,第三個參數是action執行后把執行后的內容填入到AjaxOptions中。至於AjaxOptions的作用,我們會在后面講解Ajax的時候專門進行講解。
那么本章就到這里吧,下一章我們打算寫其他的ActionResult的,但是由於這一章中出現了@Ajax的用法,那么我在下一章中老魏講解一下@Ajax輔助方法吧!