mvc JsonP 跨域訪問實現

  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
            };
        }
    }
}
View Code


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 + ");");
            }
        }
    }
}
View Code

 

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);
        }

    }
}
View Code

 

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;
        }
    }
}
View Code

 

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;
                }
            }
        });
View Code

 

 

So,EveryThing is oK!Come On!ide

相關文章
相關標籤/搜索