JSONP可以幫我們解決跨域訪問的問題。JSONP is JSON With Padding. 這里我們將不再解釋其原理。我們來看在ASP.NET MVC 3 如何實現。首先我們需要定義一個JsonpResult. 代碼像這樣, 直接繼承自JsonResult, override了ExecuteResult方法
public class JsonpResult : JsonResult { private static readonly string JsonpCallbackName = "callback"; private static readonly string CallbackApplicationType = "application/json"; /// <summary> /// Enables processing of the result of an action method by a custom type that inherits from the <see cref="T:System.Web.Mvc.ActionResult"/> class. /// </summary> /// <param name="context">The context within which the result is executed.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="context"/> parameter is null.</exception> public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if ((JsonRequestBehavior == JsonRequestBehavior.DenyGet) && String.Equals(context.HttpContext.Request.HttpMethod, "GET")) { throw new InvalidOperationException(); } var response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) response.ContentType = ContentType; else response.ContentType = CallbackApplicationType; if (ContentEncoding != null) response.ContentEncoding = this.ContentEncoding; if (Data != null) { String buffer; var request = context.HttpContext.Request; var serializer = new JavaScriptSerializer(); if (request[JsonpCallbackName] != null) buffer = String.Format("{0}({1})", request[JsonpCallbackName], serializer.Serialize(Data)); else buffer = serializer.Serialize(Data); response.Write(buffer); } } }
接着簡單定義一個擴展方法:
public static class ContollerExtensions { /// <summary> /// Extension methods for the controller to allow jsonp. /// </summary> /// <param name="controller">The controller.</param> /// <param name="data">The data.</param> /// <returns></returns> public static JsonpResult Jsonp(this Controller controller, object data) { JsonpResult result = new JsonpResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; return result; } }
在Controller里使用它, 我們的Controller叫ApiController,其中的Action:
/// <summary> /// Get some basic information with a JSONP GET request. /// </summary> /// <remarks> /// Sample url: /// http://localhost:50211/Api/GetInformation?key=test&callback=json123123 /// </remarks> /// <param name="key">key</param> /// <returns>JsonpResult</returns> public JsonpResult GetInformation(string key) { var resp = new Models.CustomObject(); if (ValidateKey(key)) { resp.Data = "You provided key: " + key; resp.Success = true; } else { resp.Message = "unauthorized"; } return this.Jsonp(resp); } private bool ValidateKey(string key) { if (!string.IsNullOrEmpty(key)) return true; return false; }
上面的方法接收一個string的參數,接着我們在前面加一個前綴字符串,最后返回就是Jsonp Result.
傳值的Model:
public class CustomObject { public bool Success { get; set; } public object Data { get; set; } public string Message { get; set; } }
運行WebSite, 訪問 http://localhost:50211/Api/GetInformation?callback=myfunction&key=haha
我們可以看到這樣的結果:
myfunction({"Success":true,"Data":"You provided key: haha","Message":null})
好的,現在讓我們在另一個站點里使用它:
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Index</title> <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { $('.result').hide(); $('#test').click(function () { $('.result').fadeOut('fast'); $('.result').html(''); $.ajax({ url: 'http://localhost:50211/Api/GetInformation', data: { key: $('input[name=key]').val() }, type: "GET", dataType: "jsonp", jsonpCallback: "localJsonpCallback" }); }); }); function localJsonpCallback(json) { //do stuff... if (json.Success) { $('.result').html(json.Data); } else { $('.result').html(json.Message); } $('.result').fadeIn('fast'); } </script> </head> <body> <div> Enter key: <input type="text" name="key" value="some data key, this parameter is optional" /> <br /><input type="button" value="Test JSONP" id="test" /> <div class="result"> </div> </div> </body> </html>
這里使用的JQuery的Ajax來調用它, 熟悉JQuery的應該能看懂, 結果是在button下div顯示字符串:
You provided key: some data key, this parameter is optional
在這里,也可以使用getJSON方法。
好了,就這么簡單。希望對您Web開發有幫助。
您可參感興趣的文章:
Asp.net MVC 3 中 Unobtrusive javascript 與Ajax
HTML5中custom data-*特性與asp.net mvc 3 表單驗證
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog。