Created
September 13, 2012 15:27
-
-
Save ninnemana/3715076 to your computer and use it in GitHub Desktop.
Extended JsonMediaTypeFormatter to Support JSONP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Http; | |
using System.Web.Mvc; | |
using System.Web.Optimization; | |
using System.Web.Routing; | |
namespace API { | |
public class WebApiApplication : System.Web.HttpApplication { | |
protected void Application_Start() { | |
AreaRegistration.RegisterAllAreas(); | |
var config = GlobalConfiguration.Configuration; | |
config.Formatters.Insert(0, new JsonpMediaTypeFormatter()); | |
WebApiConfig.Register(GlobalConfiguration.Configuration); | |
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); | |
RouteConfig.RegisterRoutes(RouteTable.Routes); | |
BundleConfig.RegisterBundles(BundleTable.Bundles); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net.Http.Formatting; | |
using System.Net.Http.Headers; | |
using System.Threading.Tasks; | |
using System.Web; | |
namespace API { | |
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter{ | |
private string _callbackQueryParamter; | |
public JsonpMediaTypeFormatter(){ | |
SupportedMediaTypes.Add(DefaultMediaType); | |
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript")); | |
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType)); | |
} | |
public string CallbackQueryParameter{ | |
get { return _callbackQueryParamter ?? "callback"; } | |
set { _callbackQueryParamter = value; } | |
} | |
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext){ | |
string callback; | |
if(IsJsonpRequest(out callback)){ | |
return Task.Factory.StartNew(() => { | |
var writer = new StreamWriter(writeStream); | |
writer.Write(callback + "("); | |
writer.Flush(); | |
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait(); | |
writer.Write(")"); | |
writer.Flush(); | |
}); | |
} | |
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext); | |
} | |
private bool IsJsonpRequest(out string callback){ | |
callback = null; | |
switch(HttpContext.Current.Request.HttpMethod){ | |
case "POST": | |
callback = HttpContext.Current.Request.Form[CallbackQueryParameter]; | |
break; | |
default: | |
callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter]; | |
break; | |
} | |
return !string.IsNullOrEmpty(callback); | |
} | |
} | |
} |
HttpContext.Current returns null in my case (.NET 4.5). I fixed this in the following code:
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
private string _callbackQueryParamter;
private HttpRequestMessage HttpRequest;
public JsonpMediaTypeFormatter()
{
SupportedMediaTypes.Add(DefaultMediaType);
SupportedMediaTypes.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
}
public string CallbackQueryParameter
{
get { return _callbackQueryParamter ?? "callback"; }
set { _callbackQueryParamter = value; }
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type,
HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
HttpRequest = request;
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
string callback;
if (IsJsonpRequest(out callback))
{
return Task.Factory.StartNew(() =>
{
var writer = new StreamWriter(writeStream);
writer.Write(callback + "(");
writer.Flush();
base.WriteToStreamAsync(type, value, writeStream, content, transportContext).Wait();
writer.Write(")");
writer.Flush();
});
}
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
private bool IsJsonpRequest(out string callback)
{
var query = HttpUtility.ParseQueryString(HttpRequest.RequestUri.Query);
callback = query[CallbackQueryParameter];
return !string.IsNullOrEmpty(callback);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I get an error on the global.asax
Method not found: 'System.Web.Http.Services.DefaultServices System.Web.Http.HttpConfiguration.get_Services()'
Any idea what I am doing wrong?