Skip to content

Instantly share code, notes, and snippets.

@jdhuntx
Created June 21, 2012 18:21
Show Gist options
  • Save jdhuntx/2967547 to your computer and use it in GitHub Desktop.
Save jdhuntx/2967547 to your computer and use it in GitHub Desktop.
JSONP MediaTypeFormatter for ASP.NET Web API Release Candidate
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace WebApiExample.Formatting
{
/// <summary>
/// Custom WebAPI media type formatter for the streaming JSONP data to the API consumer
/// </summary>
public class JsonpFormatter : MediaTypeFormatter
{
private readonly string _callbackQueryParameter;
private readonly JsonSerializerSettings _jsonSerializerSettings;
public JsonpFormatter(JsonSerializerSettings jsonSerializerSettings, string callbackQueryParameter)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
_callbackQueryParameter = callbackQueryParameter ?? "callback";
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
private string CallbackFunction { get; set; }
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
{
var serializer = JsonSerializer.Create(_jsonSerializerSettings);
return Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(stream, Encoding.UTF8))
{
using (var jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
{
var serializer = JsonSerializer.Create(_jsonSerializerSettings);
var isJsonp = !string.IsNullOrEmpty(CallbackFunction);
return Task.Factory.StartNew(() =>
{
using (var jsonTextWriter = new JsonTextWriter(new StreamWriter(stream, Encoding.UTF8)) { CloseOutput = false })
{
if (isJsonp)
{
jsonTextWriter.WriteRaw(CallbackFunction + "(");
jsonTextWriter.Flush();
}
serializer.Serialize(jsonTextWriter, value);
jsonTextWriter.Flush();
if (isJsonp)
{
jsonTextWriter.WriteRaw(")");
jsonTextWriter.Flush();
}
}
});
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
var formatter = new JsonpFormatter(_jsonSerializerSettings, _callbackQueryParameter)
{
CallbackFunction = GetJsonCallbackFunction(request)
};
return formatter;
}
private string GetJsonCallbackFunction(HttpRequestMessage request)
{
if (request.Method != HttpMethod.Get) return null;
var query = request.RequestUri.ParseQueryString();
var queryVal = query[_callbackQueryParameter];
if (string.IsNullOrEmpty(queryVal)) return null;
return queryVal;
}
}
}
@Injac
Copy link

Injac commented Aug 24, 2013

Hi Jonathan, thanks for the code :) Here is an updated version for the current release of the WebApi: https://gist.github.com/Injac/6329543

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment