그래서 WebAPI에 JSONP 지원을 추가하는 방법에 대한 내용을 읽었습니다. 나는 그들 모두에 대해 시도했다.
그런 다음 Jsonp 포맷을 읽는 데 시간이 걸렸습니다. 필자도 Jsonp를 지원합니다.
public class JsonNetFormatter : MediaTypeFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private string _callbackQueryParameter;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
//we also support jsonp.
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private Encoding Encoding
{
get { return SupportedEncodings[0]; }
}
public string CallbackQueryParameter
{
get { return _callbackQueryParameter ?? "callback"; }
set { _callbackQueryParameter = value; }
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonNetFormatter(_jsonSerializerSettings)
{
JsonpCallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get)
return null;
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var queryVal = query[CallbackQueryParameter];
if (string.IsNullOrEmpty(queryVal))
return null;
return queryVal;
}
private string JsonpCallbackFunction { get; set; }
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(readStream, SupportedEncodings[0]))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var isJsonp = JsonpCallbackFunction != null;
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(writeStream, Encoding)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(JsonpCallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
}
이 그런 다음 global.asax.cs이 작은 아름다움 추가 :
private static void AddJsonFormatterAndSetDefault()
{
var serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
var jsonFormatter = new JsonNetFormatter(serializerSettings);
jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter);
}
를 그리고 위해 Application_Start
에서 호출이 나를 위해 작동 여기
는 클래스입니다 json과 jsonp를 모두 지원합니다.
의 mediatypeformatter은 할 필요가 json과 jsonp가 모두 작동하도록 단일 하위 클래스로 결합되었습니다 (WebapiContrib.Formatting.Jsonp Nuget 패키지를 사용함). 트릭을 수행하는 것으로 보이는 해결책을 찾았습니다. http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web- API – AesopWaits