NetCore MVC 中如何实现JSONP格式的返回

在jquery ajax请求中,有时候设计到跨域,我们需要采用JSONP的格式进行处理,服务端也需要返回 callback 等内容

但是在MVC中,默认只有JsonResult 的返回类型,没有支持JSONP的。

这时候我们有以下 2种方案,实现我们JSONP 格式返回的需求。

第一种方案,也是最简单的方案:

采用ContentResult 返回,代码如下:

 public ContentResult Test2(string callback)
        {
            var data = new { code = 2 };
            string str = callback + "(" + Newtonsoft.Json.JsonConvert.SerializeObject(data) + ")";
            return new ContentResult() { Content = str, ContentType = "application/json" };
        }

 

第二种方案呢,我们自己写一个JSONP 类的扩展,代码如下:

    public class JsonpResult : Microsoft.AspNetCore.Mvc.JsonResult
    {
        //
        // 摘要:
        //     Creates a new Microsoft.AspNetCore.Mvc.JsonResult with the given value.
        //
        // 参数:
        //   value:
        //     The value to format as JSON.
        public JsonpResult(object value) : base(value) { }
        //
        // 摘要:
        //     Creates a new Microsoft.AspNetCore.Mvc.JsonResult with the given value.
        //
        // 参数:
        //   value:
        //     The value to format as JSON.
        //
        //   serializerSettings:
        //     The serializer settings to be used by the formatter.
        //     When using System.Text.Json, this should be an instance of System.Text.Json.JsonSerializerOptions.
        //     When using Newtonsoft.Json, this should be an instance of JsonSerializerSettings.
        public JsonpResult(object value, object serializerSettings) : base(value, serializerSettings) { }
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        public override void ExecuteResult(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            //获取callback
            string callback = context.HttpContext.Request.Query["callback"];
            string result = string.Empty;
            if (SerializerSettings is Newtonsoft.Json.JsonSerializerSettings)
            {
                if (SerializerSettings != null)
                {
                    var setting = SerializerSettings as Newtonsoft.Json.JsonSerializerSettings;
                    result = Newtonsoft.Json.JsonConvert.SerializeObject(Value, settings: setting);
                }
                else
                {
                    result = Newtonsoft.Json.JsonConvert.SerializeObject(Value);
                }
            }
            else
            {
                if (SerializerSettings != null)
                {
                    var setting = SerializerSettings as System.Text.Json.JsonSerializerOptions;
                    result = System.Text.Json.JsonSerializer.Serialize(Value, options: setting);
                }
                else
                {
                    result = System.Text.Json.JsonSerializer.Serialize(Value);
                }

            }
            context.HttpContext.Response.ContentType = "application/json";
            context.HttpContext.Response.WriteAsync(callback + "(" + result + ")");
        }

        public override Task ExecuteResultAsync(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            //获取callback
            string callback = context.HttpContext.Request.Query["callback"]; //这边是固定了callback名称,若不固定,可定义参数传进来
            string result = string.Empty;
            if (SerializerSettings is Newtonsoft.Json.JsonSerializerSettings)
            {
                if(SerializerSettings!=null)
                {
                    var setting = SerializerSettings as Newtonsoft.Json.JsonSerializerSettings;
                        result = Newtonsoft.Json.JsonConvert.SerializeObject(Value,settings:setting);
                }
                else
                {
                    result = Newtonsoft.Json.JsonConvert.SerializeObject(Value);
                }
            }
            else
            {
                if (SerializerSettings != null)
                {
                    var setting = SerializerSettings as System.Text.Json.JsonSerializerOptions;
                    result = System.Text.Json.JsonSerializer.Serialize(Value, options: setting);
                }
                else
                {
                    result = System.Text.Json.JsonSerializer.Serialize(Value);
                }
               
            }
            context.HttpContext.Response.ContentType = "application/json";
            context.HttpContext.Response.WriteAsync(callback + "(" + result + ")");
            return Task.CompletedTask;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return base.ToString();
        }
    }

以上,我们就完成了扩展,然后应用如下:

      public JsonpResult Test()
        {
            var data = new { code = 1 };
            return new JsonpResult(new { code = 1 });
        }

这样,我们也可以完成jsonp格式的返回处理了。

若是要像Json(数据),这样调用的,直接定义个基类控制器,然后业务控制器继承该基类控制器即可。如

    public class JsonpBaseController : Controller
    {
        public JsonpResult Jsonp(object data)
        {
            return new JsonpResult(data);
        }
    }

然后 做些继承:    public class HomeController : JsonpBaseController

就可以直接使用了

      public JsonpResult Test()
        {
            var data = new { code = 1 };
            return Jsonp(data);
        }

===================================

更多分享,请大家关注我的个人公众号:

 

posted @ 2022-12-07 17:40  黄明辉  阅读(343)  评论(0编辑  收藏  举报