2014-03-31 53 views
1

我想讓我的.net MVC web api返回JSONP。我有一個對JsonpMediaTypeFormatter的引用,實現了一個基於它的JsonFormatter,在我的Application_Start()函數中註冊了它,並且客戶端的json調用了'& callback =?'仍然沒有與jsonp回調包裝返回...我錯過了什麼?Web服務不包裝JSONP回調中的JSON?

我試着在格式化程序類中設置一個斷點,它似乎並沒有被調用?

碼位:

格式化:

/// <summary> 
/// Handles JsonP requests when requests are fired with text/javascript 
/// </summary> 
public class JsonpFormatter : JsonMediaTypeFormatter 
{ 

    public JsonpFormatter() 
    { 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); 

     JsonpParameterName = "callback"; 
    } 

    /// <summary> 
    /// Name of the query string parameter to look for 
    /// the jsonp function name 
    /// </summary> 
    public string JsonpParameterName { get; set; } 

    /// <summary> 
    /// Captured name of the Jsonp function that the JSON call 
    /// is wrapped in. Set in GetPerRequestFormatter Instance 
    /// </summary> 
    private string JsonpCallbackFunction; 


    public override bool CanWriteType(Type type) 
    { 
     return true; 
    } 

    /// <summary> 
    /// Override this method to capture the Request object 
    /// </summary> 
    /// <param name="type"></param> 
    /// <param name="request"></param> 
    /// <param name="mediaType"></param> 
    /// <returns></returns> 
    public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType) 
    { 
     var formatter = new JsonpFormatter() 
     { 
      JsonpCallbackFunction = GetJsonCallbackFunction(request) 
     }; 

     // this doesn't work unfortunately 
     //formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings; 

     // You have to reapply any JSON.NET default serializer Customizations here  
     formatter.SerializerSettings.Converters.Add(new StringEnumConverter()); 
     formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; 

     return formatter; 
    } 


    public override Task WriteToStreamAsync(Type type, object value, 
            Stream stream, 
            HttpContent content, 
            TransportContext transportContext) 
    { 
     if (string.IsNullOrEmpty(JsonpCallbackFunction)) 
      return base.WriteToStreamAsync(type, value, stream, content, transportContext); 

     StreamWriter writer = null; 

     // write the pre-amble 
     try 
     { 
      writer = new StreamWriter(stream); 
      writer.Write(JsonpCallbackFunction + "("); 
      writer.Flush(); 
     } 
     catch (Exception ex) 
     { 
      try 
      { 
       if (writer != null) 
        writer.Dispose(); 
      } 
      catch { } 

      var tcs = new TaskCompletionSource<object>(); 
      tcs.SetException(ex); 
      return tcs.Task; 
     } 

     return base.WriteToStreamAsync(type, value, stream, content, transportContext) 
        .ContinueWith(innerTask => 
        { 
         if (innerTask.Status == TaskStatus.RanToCompletion) 
         { 
          writer.Write(")"); 
          writer.Flush(); 
         } 

        }, TaskContinuationOptions.ExecuteSynchronously) 
        .ContinueWith(innerTask => 
        { 
         writer.Dispose(); 
         return innerTask; 

        }, TaskContinuationOptions.ExecuteSynchronously) 
        .Unwrap(); 
    } 

    /// <summary> 
    /// Retrieves the Jsonp Callback function 
    /// from the query string 
    /// </summary> 
    /// <returns></returns> 
    private string GetJsonCallbackFunction(HttpRequestMessage request) 
    { 
     if (request.Method != HttpMethod.Get) 
      return null; 

     var query = HttpUtility.ParseQueryString(request.RequestUri.Query); 
     var queryVal = query[this.JsonpParameterName]; 

     if (string.IsNullOrEmpty(queryVal)) 
      return null; 

     return queryVal; 
    } 
} 

註冊:

protected void Application_Start() 
    { 
     InitializeDatabase(); 
     MapModels(); 

     GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpFormatter()); 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
    } 
+0

你回來了什麼? –

+0

@JonathanM它返回錯誤'[回調函數]沒有被調用。'響應文本是未包裝的普通JSON對象。 – Alex

回答

1

嘗試使用熔核包WebApiContrib.Formatting.Jsonp JSONP格式化,在Application_Start

註冊它像這樣
GlobalConfiguration.Configuration.AddJsonpFormatter(); 

我剛剛爲我正在開發的東西創建了一個MCV4項目,並且需要相同的東西,添加了一個API控制器,並且可以對其進行JSONP調用。該項目的網站是:

https://github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp