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); }
===================================
更多分享,请大家关注我的个人公众号: