by thorhalvor

JSONP in ASP.NET MVC 3

When consuming a JSON REST API using AJAX the message is send as a XMLHttpRequest. Due to security reasons this is not allowed cross domain. Instead of returning the data as core JSON, JSONP is often used. The data will then not be parsed by the JSON parser but evaluated by the JavaScript interpreter.

Returning JSONP data does not come out of the box in ASP.NET MVC 3, but you can write a simple wrapper like this:

using System.Web.Mvc;
 
public class JsonpResult : JsonResult
{
    private const string CALLBACK_QUERYSTRING = "callback";
    private const string CALLBACK_CONTENTTYPE = "application/x-javascript";
 
    public override void ExecuteResult(ControllerContext controllerContext)
    {
        if (controllerContext != null)
        {
            var request = controllerContext.HttpContext.Request;
            object callback = request[CALLBACK_QUERYSTRING];
            if (callback == null)
            {
                controllerContext.RouteData.Values.TryGetValue(CALLBACK_QUERYSTRING, out callback);
            }
 
            var hasCallback = !string.IsNullOrWhiteSpace(callback ==null ? "" : callback as string);
 
            if (hasCallback)
            {
                SetContentTypeIfEmpty();
                var response = controllerContext.HttpContext.Response;
 
                response.Write(callback);
                response.Write("(");
                base.ExecuteResult(controllerContext);
                response.Write(")");
            }
            else
            {
                base.ExecuteResult(controllerContext);
            }
        }
    }
 
    private void SetContentTypeIfEmpty()
    {
        if (string.IsNullOrWhiteSpace(base.ContentType))
        {
            base.ContentType = CALLBACK_CONTENTTYPE;
        }
    }
}

 

It is now possible to just replace the jsonresult with jsonpresult in the code. If no callback is given it will work as normal.

        //return new JsonResult();
        return new JsonpResult();

 

When sending the request GET http://localhost/Website/Products/All?callback=myCallbackFunction the data will be wrapped like this: (same method used in last blogpost)

jsonp