程式碼來自《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,筆記完成,記錄下來以防以後 用到可以參考參考。