MVC Controller 的action代碼返回JsonResult的保持原樣,仍是返回JsonResult。爲須要跨域訪問的Controller action接口寫一個基類Controller,名爲 BaseController,而後跨域的Controller 繼承該Controller。javascript
BaseController中 重寫 OnActionExecuted 方法,將 filterContext.Result = new JsonpResult{......},且給本身定義的且繼承自JsonpResult的相關屬性賦值,則能夠返回本身想要的JsonpResult。java
1. BaseController 代碼以下:ajax
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net.Mime; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Helpers; using System.Web.Mvc; using CYP.Activity.Common; using Microsoft.Practices.ServiceLocation; namespace CYP.Activity.Web.Mvc { public class BaseController : Controller { private readonly JsonRequestBehavior _allowGet = (BaseConfig.AllowGet) ? JsonRequestBehavior.AllowGet : JsonRequestBehavior.DenyGet; protected override void OnActionExecuting(ActionExecutingContext filterContext) { var incomingOrigin = HttpContext.Request.Headers.Get("Origin"); //判斷來源的域 是否爲 可訪問的域,可訪問則能夠返回數據 if ((!string.IsNullOrEmpty(incomingOrigin)) && BaseConfig.DomainUrl.IndexOf(incomingOrigin, StringComparison.OrdinalIgnoreCase) > -1) { HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", incomingOrigin); } //if (HttpContext.Request.HttpMethod == "OPTIONS") //{ // HttpContext.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); // HttpContext.Response.AddHeader("Access-Control-Allow-Headers", // "Content-Type, Authorization, Accept,X-Requested-With"); // HttpContext.Response.End(); //} } protected override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext == null) throw new ArgumentNullException("filterContext"); // 查看是否包含 callback var callbackparam = filterContext.HttpContext.Request.QueryString["callbackparam"]; var exceptionMsg = string.Empty; if ((_allowGet == JsonRequestBehavior.DenyGet) && String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET")) { exceptionMsg = "Deny Get Request."; //throw new InvalidOperationException("Deny Get Request"); } var result = filterContext.Result as JsonResult; if ((!string.IsNullOrEmpty(callbackparam)) && callbackparam.Length > 0) { if (result == null) { exceptionMsg = "Result is null."; //throw new InvalidOperationException("Result is null."); } } filterContext.Result = new JsonpResult { ContentEncoding = (result == null || (!string.IsNullOrEmpty(exceptionMsg))) ? Encoding.UTF8 : result.ContentEncoding, ContentType = (result == null || (!string.IsNullOrEmpty(exceptionMsg))) ? "" : result.ContentType, Data = (result == null || (!string.IsNullOrEmpty(exceptionMsg))) ? exceptionMsg : result.Data, Callback = callbackparam }; } } }
2.JsonpResult 代碼以下:數據庫
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.Script.Serialization; namespace CYP.Activity.Common { public class JsonpResult : JsonResult { public string Callback { get; set; } //private readonly JsonRequestBehavior _allowGet = (BaseConfig.AllowGet) // ? JsonRequestBehavior.AllowGet // : JsonRequestBehavior.DenyGet; public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException("context"); //if ((_allowGet == JsonRequestBehavior.DenyGet) && // String.Equals(context.HttpContext.Request.HttpMethod, "GET")) //{ // throw new InvalidOperationException(); //} HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) response.ContentType = ContentType; else response.ContentType = "application/javascript"; if (ContentEncoding != null) response.ContentEncoding = ContentEncoding; if ((string.IsNullOrEmpty(Callback)) || Callback.Length == 0) Callback = context.HttpContext.Request.QueryString["callback"]; if (Data != null) { var serializer = new JavaScriptSerializer(); string ser = serializer.Serialize(Data); response.Write(Callback + "(" + ser + ");"); } } } }
3.Controller繼承 BaseController 代碼以下:json
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Helpers; using System.Web.Mvc; using System.Web.Script.Serialization; using System.Web.UI.WebControls; using CYP.Activity.Common; using CYP.Activity.Web.Mvc; using CYP.ActivityOrder.Domain; using Microsoft.Practices.ServiceLocation; using CYP.ActivityOrder.Service; namespace CYP.Activity.Web.Controllers { public class ActiOrderController : BaseController { private readonly IActiOrderService _actiOrdersService; private readonly JsonRequestBehavior _allowGet = (BaseConfig.AllowGet) ? JsonRequestBehavior.AllowGet : JsonRequestBehavior.DenyGet; //private readonly JavaScriptSerializer _serializer = new JavaScriptSerializer(); public ActiOrderController() { _actiOrdersService = ServiceLocator.Current.GetInstance<IActiOrderService>(); } /// <summary> /// 獲取數據庫時間戳 /// </summary> /// <returns></returns> [JsonException] public JsonResult GetDbTime(string callbackparam) { var result = _actiOrdersService.GetDbTime(); return Json(new { Success = true, DbTime = result }, _allowGet); } /// <summary> /// 獲取 總成交車輛數 / 總成交金額 / 上一小時成交量 /// </summary> /// <returns></returns> [JsonException] public JsonResult GetTotalActivityOrder(string callbackparam, int previous = 0) { var result = _actiOrdersService.GetTotalActivityOrder(previous); return Json(new { Success = true, Data = result }, _allowGet); } } }
4.繼承自HandleErrorAttribute的JsonExceptionAttribute捕獲異常的代碼以下:跨域
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.Script.Serialization; using System.Web.UI.WebControls; namespace CYP.Activity.Common { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class JsonExceptionAttribute : HandleErrorAttribute { private readonly CYPLog.TextLogger _globalErrorLog = CYPLog.TextLogManager.Create(typeof(JsonExceptionAttribute)); public override void OnException(ExceptionContext filterContext) { //記錄錯誤 _globalErrorLog.Error(string.Format("在請求連接【{0}】時產生異常,異常緣由:【{1}】", filterContext.HttpContext.Request.Url, filterContext.Exception.ToString())); var callbackparam = filterContext.HttpContext.Request.QueryString["callbackparam"]; if (!filterContext.ExceptionHandled) { var result = filterContext.Result as JsonResult; if (result == null) { throw new InvalidOperationException("JsonExceptionAttribute must be applied only " + "on controllers and actions that return a JsonResult object."); } filterContext.Result = new JsonpResult { ContentEncoding = result.ContentEncoding, ContentType = result.ContentType, Data = result.Data, Callback = callbackparam }; } filterContext.ExceptionHandled = true; } } }
5.頁面Js調用代碼以下:app
$.ajax({ url: actPrefix + 'ActiOrder/GetDbTime', cache: false, type: "POST", dataType: "jsonp", jsonp: "callbackparam", //服務端用於接收callback調用的function名的參數 jsonpCallback: "success_getTime", //callback的function名稱 success: function(data) { if (data != null && data.DbTime != null && data.Success) { timeDif = new Date().getTime() - data.DbTime; } } });
So,EveryThing is oK!Come On!ide