ASP.NET Web API 自定义MediaType实现jsonp跨域调用

  代码来自《ASP.NET Web API 2 框架揭秘》一书。

  直接上代码:

  

复制代码
 /// <summary>
    /// 自定义jsonp MediaType
    /// </summary>
    public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
    {
        //callback参数
        public string Callback { get; private set; }
        public JsonpMediaTypeFormatter(string callback = null)
        {
            this.Callback = callback;
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            //如果callback不存在,直接调用父类方法
            if (string.IsNullOrEmpty(this.Callback))
            {
                return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
            }
            try
            {
                //否则调用重写的方法
                this.WriteToStream(type, value, writeStream, content);
                return Task.FromResult<AsyncVoid>(new AsyncVoid());
            }
            catch(Exception ex)
            {
                TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();
                source.SetException(ex);
                return source.Task;
            }
        }


        private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
        {
            JsonSerializer serializer = JsonSerializer.Create(this.SerializerSettings);
            using (StreamWriter writer = new StreamWriter(writeStream,this.SupportedEncodings.First())) {
                using (JsonTextWriter jsonTextWriter = new JsonTextWriter(writer) { CloseOutput = false }) {
                    //添加callback(json)
                    jsonTextWriter.WriteRaw(this.Callback + "(");
                    serializer.Serialize(jsonTextWriter, value);
                    jsonTextWriter.WriteRaw(")");
                }
            }
        }

        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {

            if (request.Method != HttpMethod.Get) { return this; }
            string callback;
            if (request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value).TryGetValue("callback", out callback)) {
                return new JsonpMediaTypeFormatter(callback);
            }
            return this;
        }

        [StructLayout(LayoutKind.Sequential, Size = 1)]
        private struct AsyncVoid { }
    }
复制代码

  然后在Global.asax中将JsonpMediaTypeFormatter加入

  

复制代码
 protected void Application_Start()
        { 
            //加入jsonpMediaTypeFormatter
            GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
            AreaRegistration.RegisterAllAreas();
         
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
复制代码

  Demo演示:

  我在localhost:55950 用jquery 调用api(http://localhost:55599/api/search?key=%E7%83%A7%E7%81%AB&from=0&size=10)

  

  得到结果如图:

  

  成功调用。不过书上说,这种方法仅限于get方法。

  OK,笔记完成,记录下来以防以后 用到可以参考参考。

posted @   丶Pz  阅读(1173)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示
+

"大爷常来玩呀"

微信支付