What's required to have our WebApi supports multiple Formatter?
Here what i've:
In my gloabl file, i've put
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
JsonpMediaTypeFormatter is custom Jsonp formatter that i've
After this, when i call,
function jsonpCallback(data) {
alert('in' + data);
var list = $('#courses');
for (var i = 0; i < data.length; i++) {
var course = data[i];
list.append('<li>' + course.name + '</li>');
}
}
$.getJSON("http://localhost:64009/api/courses?callback=?", null, jsonpCallback);
It worked.
But, from my global file, if i remove
GlobalConfiguration.Configuration.Formatters.Clear();
Then it doesn't work.
What if i want to support multiple formatter?
As i can use HttpClient for CORS and ask for xml or json or jsop?
You can add as many formetters as you need. Just use Add to add to the end or use Insert to add to a specific location in the collection.
You should not really clear all formatters, this will render the whole stack useless. You can remove individual formatter by using Remove or RemoveAt.
You can have multiple formatters supporting the same media type. In that case order of the formatters becomes the key point for the framework to choose the formatter: the first one wins.
If you see the response, it gives me json format and not jsonp format even i specify in my ajax call that i need jsonp format.
When i put breakpoint @ my jsonp formatter, it's not even reaching that point.
Last point:
if i try "Insert" instead "Add", it works as i'm inserting @ 0th index
GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
You need to pad it yourself. JSONP is JSON anyway.
function jsonp(url, callback) {
// create a unique id var id = "_" + (new Date()).getTime();
// create a global callback handler window[id] = function (result) {
// forward the call to specified handler if (callback)
callback(result);
// clean up: remove script and id var sc = document.getElementById(id);
sc.parentNode.removeChild(sc);
window[id] = null;
}
url = url.replace("callback=?", "callback=" + id);
// create script tag that loads the 'JSONP script' // and executes it calling window[id] function var script = document.createElement("script");
script.setAttribute("id", id);
script.setAttribute("src", url);
script.setAttribute("type", "text/javascript");
document.body.appendChild(script);
}
From "http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API", last paragraph:
Note that I added the formatter at the top of the list of formatters, rather than adding it to the end which is required. The JSONP formatter needs to fire before any other JSON formatter since it relies on the JSON formatter to encode the actual JSON data.
If you reverse the order the JSONP output never shows up. So, in general when adding new formatters also try to be aware of the order of the formatters as they are added.
This explains why:
it's not working when i use GlobalConfiguration
.Configuration .Formatters.Add(JsonpFormatter)
It's working when i user GlobalConfiguration
.Configuration .Formatters.Insert(0, JsonpFormatter)
I think Microsoft should improve this and make it like:
Order for Formatter shouldn't matter if request specifically menstioned dataType/Accepts (json, xml, jsonp, etc.)
if request doesn't specify dataType/Accepts, then by default it takes first formatter which is json.
I research more on last paragraph:
From "http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API", last paragraph:
Note that I added the formatter at the top of the list of formatters, rather than adding it to the end which is required. The JSONP formatter needs to fire before any other JSON formatter since it relies on the JSON formatter to encode the actual JSON data.
If you reverse the order the JSONP output never shows up. So, in general when adding new formatters also try to be aware of the order of the formatters as they are added.
I found something wiered.
1. I keep following in my global file (project2: http://localhost:64009/):
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
2. From the same project (project2), i call the following:
$.ajax({
url: "/api/courses",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "jsonpCallback"
});
And it worked! Menas it returns jsonp even we've added jsonp at last and not inserted @ 0th index
3. The wiered thing is:
From another project (project1: http://localhost:53723/, Cross domain), when i call the same webapi in project2, it returns json but not jsonp:
$.ajax({
url: "http://localhost:64009/api/courses",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "jsonpCallback"
});
So last paragraph is correct for Cross domain and not for same domain?
One more question on unknown format:
http://weblogs.asp.net/gunnarpeipman/archive/2012/04/19/asp-net-web-api-how-content-negotiation-works.aspx?CommentPosted=true#commentmessage
I've added jsonp formatter to my GlobalConfiguration
SCV
Member
27 Points
23 Posts
Asp.net WebApi supports json, xml, jsonp?
May 05, 2012 11:58 PM|LINK
What's required to have our WebApi supports multiple Formatter?
Here what i've:
In my gloabl file, i've put
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
JsonpMediaTypeFormatter is custom Jsonp formatter that i've
After this, when i call,
function jsonpCallback(data) {
alert('in' + data);
var list = $('#courses');
for (var i = 0; i < data.length; i++) {
var course = data[i];
list.append('<li>' + course.name + '</li>');
}
}
$.getJSON("http://localhost:64009/api/courses?callback=?", null, jsonpCallback);
It worked.
But, from my global file, if i remove
GlobalConfiguration.Configuration.Formatters.Clear();
Then it doesn't work.
What if i want to support multiple formatter?
As i can use HttpClient for CORS and ask for xml or json or jsop?
Please advice
aliostad
Member
228 Points
55 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 09:10 AM|LINK
You can add as many formetters as you need. Just use Add to add to the end or use Insert to add to a specific location in the collection.
You should not really clear all formatters, this will render the whole stack useless. You can remove individual formatter by using Remove or RemoveAt.
You can have multiple formatters supporting the same media type. In that case order of the formatters becomes the key point for the framework to choose the formatter: the first one wins.
Have a look at these articles:
http://www.strathweb.com/2012/04/different-mediatypeformatters-for-same-mediaheadervalue-in-asp-net-web-api/
http://weblogs.asp.net/gunnarpeipman/archive/2012/04/20/asp-net-web-api-extending-content-negotiation-with-new-formats.aspx
http://byterot.blogspot.co.uk/2012/04/aspnet-web-api-series-part-5.html
SCV
Member
27 Points
23 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 01:44 PM|LINK
Thanks Aliostad.
Here what i've:
In my project2, global file, i've addedd
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
I'm trying to call project2(http://localhost:64009) from project1(http://localhost:53723)
$.ajax({
url: "http://localhost:64009/api/courses",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "jsonpCallback"
});
Specifying that i require jsonp format and project2 supports jsonp format and also we added custom jsonp format to Configuration.
But when i make that $.ajax call, i get the following in fiddler:
Request:
GET http://localhost:64009/api/courses?callback=jsonpCallback&_=1336310868941 HTTP/1.1
Host: localhost:64009
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost:53723/
Pragma: no-cache
Cache-Control: no-cache
Response:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 06 May 2012 13:27:50 GMT
X-AspNet-Version: 4.0.30319
Transfer-Encoding: chunked
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Connection: Close
49
[{"id":0,"name":".net"},{"id":1,"name":"oData"},{"id":2,"name":"WebApi"}]
0
If you see the response, it gives me json format and not jsonp format even i specify in my ajax call that i need jsonp format.
When i put breakpoint @ my jsonp formatter, it's not even reaching that point.
Last point:
if i try "Insert" instead "Add", it works as i'm inserting @ 0th index
GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpMediaTypeFormatter());
Any idea? What i'm missing.
aliostad
Member
228 Points
55 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 02:27 PM|LINK
You need to pad it yourself. JSONP is JSON anyway.
Working example here:
http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API
SCV
Member
27 Points
23 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 03:10 PM|LINK
Thanks Aliostad.
From "http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API", last paragraph:
Note that I added the formatter at the top of the list of formatters, rather than adding it to the end which is required. The JSONP formatter needs to fire before any other JSON formatter since it relies on the JSON formatter to encode the actual JSON data. If you reverse the order the JSONP output never shows up. So, in general when adding new formatters also try to be aware of the order of the formatters as they are added.
This explains why:
it's not working when i use GlobalConfiguration .Configuration .Formatters.Add(JsonpFormatter)
It's working when i user GlobalConfiguration .Configuration .Formatters.Insert(0, JsonpFormatter)
I think Microsoft should improve this and make it like:
Order for Formatter shouldn't matter if request specifically menstioned dataType/Accepts (json, xml, jsonp, etc.)
if request doesn't specify dataType/Accepts, then by default it takes first formatter which is json.
Any comment on this?
SCV
Member
27 Points
23 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 03:25 PM|LINK
I research more on last paragraph:
From "http://www.west-wind.com/weblog/posts/2012/Apr/02/Creating-a-JSONP-Formatter-for-ASPNET-Web-API", last paragraph:
Note that I added the formatter at the top of the list of formatters, rather than adding it to the end which is required. The JSONP formatter needs to fire before any other JSON formatter since it relies on the JSON formatter to encode the actual JSON data. If you reverse the order the JSONP output never shows up. So, in general when adding new formatters also try to be aware of the order of the formatters as they are added.
I found something wiered.
1. I keep following in my global file (project2: http://localhost:64009/):
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
2. From the same project (project2), i call the following:
$.ajax({
url: "/api/courses",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "jsonpCallback"
});
And it worked! Menas it returns jsonp even we've added jsonp at last and not inserted @ 0th index
3. The wiered thing is:
From another project (project1: http://localhost:53723/, Cross domain), when i call the same webapi in project2, it returns json but not jsonp:
$.ajax({
url: "http://localhost:64009/api/courses",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "jsonpCallback"
});
So last paragraph is correct for Cross domain and not for same domain?
Please advice!
formatdate
SCV
Member
27 Points
23 Posts
Re: Asp.net WebApi supports json, xml, jsonp?
May 06, 2012 05:19 PM|LINK
One more question on unknown format:
http://weblogs.asp.net/gunnarpeipman/archive/2012/04/19/asp-net-web-api-how-content-negotiation-works.aspx?CommentPosted=true#commentmessage
I've added jsonp formatter to my GlobalConfiguration
GlobalConfiguration.Configuration.Formatters.Add(new JsonpMediaTypeFormatter());
Then i try to call my webapi using format that's not supported..that means it should return json:
$.ajax({
url: "/api/courses",
dataType: "x-vcard",
type: "GET",
success: function (data) {
var list = $('#courses');
for (var i = 0; i < data.length; i++) {
var course = data[i];
list.append('<li>' + course.name + '</li>');
}
},
statusCode: {
401: function () {
alert('Login please');
},
200: function (jqXHR, textStatus, errorThrown) {
alert('succcess');
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('error');
alert(jqXHR.statusText + " ----- " + jqXHR.responseText);
}
});
Here's request/response from fiddler:
Request:
GET localhost/.../courses HTTP/1.1
Host: localhost:64009
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Referer: localhost/.../courses
Response:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 06 May 2012 16:01:07 GMT
X-AspNet-Version: 4.0.30319
Transfer-Encoding: chunked
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json
Connection: Close
49
[{"id":0,"name":".net"},{"id":1,"name":"oData"},{"id":2,"name":"WebApi"}]
0
And it returns json, but my ajax callback goes to error and shows the following message:
parseerror - [{"id":0,"name":".net"},{"id":1,"name":"oData"},{"id":2,"name":"WebApi"}]
why it's not calling success callback function?