【发布时间】:2014-05-11 04:55:35
【问题描述】:
我正在尝试让我的 .net MVC Web api 返回 JSONP。我有一个对 JsonpMediaTypeFormatter 的引用,基于它实现了一个 JsonFormatter,在我的 Application_Start() 函数中注册了它......以及使用“&callback=?”的客户端 json 调用jsonp 回调包装仍然没有返回......我错过了什么吗?
我尝试在格式化程序类中设置断点,它似乎从未被调用过?
代码位:
格式化程序:
/// <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);
}
【问题讨论】:
-
你要返回什么?
-
@JonathanM 它返回一个错误“[回调函数]没有被调用。”响应文本是未包装的纯 JSON 对象。
标签: jquery ajax asp.net-web-api callback jsonp