JSONP request succeeds but returns no data
I am having trouble getting JSONP data from one of my sites. On the site, Data is provided using the following MVC2 controller action:
public JsonResult JsonList(string key) {
var consultants = rep.FindAll().Where(c => c.IsActive).Select(c => new ConsultantJsonItem { Firstname = c.Firstname, Surname = c.Surname });
return Json(consultants, "application/json");
}
On site B, I am using jQuery to fetch JSON like:
$.ajax({
url: 'http://www.siteA.com/controller/jsonaction/',
dataType: 'JSONP',
crossDomain: true,
success: function (json) {
alert("success"); // THIS DISPLAYS
alert(json); // THIS IS ALWAYS EMPTY
},
error: function (xhr, status, error) {
alert(status); // NOT CALLED
}
});
In the Firebug console, I can see that the response completed correctly with a code of 200 and I can see that the response length of the response is 11516 bytes, but the response tab is completely empty and jQuery won't give me any data to work with.
Can anyone tell me why this is?
Note. This site uses jQuery 1.4.2
source to share
You are returning JSON which is not the same as JSONP:
return Json(consultants, "application/json");
The fact that you've installed dataType: 'JSONP'
on the client is only half the work you have to get done. The other half is on the server.
Checkout the following response , which illustrates how you can create a custom JsonpResult
one that will use the callback query string parameter to wrap the response in JSONP.
So:
public class JsonpResult : ActionResult
{
private readonly object _obj;
public JsonpResult(object obj)
{
_obj = obj;
}
public override void ExecuteResult(ControllerContext context)
{
var serializer = new JavaScriptSerializer();
var callbackname = context.HttpContext.Request["callback"];
var jsonp = string.Format("{0}({1})", callbackname, serializer.Serialize(_obj));
var response = context.HttpContext.Response;
response.ContentType = "application/json";
response.Write(jsonp);
}
}
and then:
public ActionResult JsonList(string key)
{
var consultants = rep.FindAll().Where(c => c.IsActive).Select(c => new ConsultantJsonItem { Firstname = c.Firstname, Surname = c.Surname });
return new JsonpResult(consultants);
}
and on the client:
$.ajax({
url: 'http://www.siteA.com/controller/jsonaction/',
jsonp: 'callback',
dataType: 'jsonp',
success: function (json) {
alert(json);
}
});
source to share
The answer you are giving is not JSONP .. it is JSON. JSONP needs to be wrapped with a function name;
foo({ "valid": "json" });
For more information on why JSONP needs to be surrounded by a function name (e.g. indented), and how it gets around SOP restrictions, see this answer .
To get JSONP back in ASP.NET you need to do it manually, like in this question; ASP.net MVC returns JSONP
In your case, you shouldn't even see the "success" warning; but that was a bug in the version of jQuery you are using (1.4.2). If jQuery doesn't support crossDomain
up to 1.5, and it definitely checks dataType
jsonp
(not jsonp
), you end up with a standard JSON request XMLHttpRequest
that the browser aborts to enforce SOP. However, jQuery was misinterpreting the state of the interrupted object as completed .
This ultimately resulted in a call, data
not an initialized ( ""
).
source to share