Skip to content

Instantly share code, notes, and snippets.

@ninnemana
Created September 13, 2012 15:27
Show Gist options
  • Save ninnemana/3715076 to your computer and use it in GitHub Desktop.
Save ninnemana/3715076 to your computer and use it in GitHub Desktop.
Extended JsonMediaTypeFormatter to Support JSONP
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);
}
}
}
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);
}
}
}
@mudithaa
Copy link

mudithaa commented May 2, 2013

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?

@bmellink
Copy link

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