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