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,笔记完成,记录下来以防以后 用到可以参考参考。
多学点,总不会吃亏的。