1. Introduction
- This tutorial is supposed to serve dual purpose:
- To demonstrate an ASP.NET JSON proxy which pulls data from a database (or XML file/web-service) and serves it as JSON and
- Perform cross domain requests using JavaScript (using dynamic script tags).
- To make our article a bit more comprehensive, I have included a basic JSON web service in jsonproxy.v2.zip of this article (above).
This gives us an idea of how a JSON web service can be consumed using jQuery/JavaScript AJAX. This is a better approach for intra domain JSON requests.
- Our JSON web service returns us the data as JSON/XML on the basis of the Content Type we request from it.
- We include a client "jsonServiceClient.htm" which consumes our web-service.
All the above scripts are independent and usable in different scenarios. Our
JSON proxy page resides on the server and can be consumed locally using the jQuery.ajax
or jQuery.getJSON
methods.
This solution is a combination of various techniques brought together to present a single approach for "hosting" server side data
as JSON and "consuming" it using jQuery/JavaScript.
For accessing the data on local domain, we can create an ASP.NET web-service, which is a better and easier approach. Then we can call our web-service using JavaScript AJAX
or jQuery.ajax or SOAP. (Example attached with this article.)
However, for cross domain requirements, our JSON-Proxy can be used to host data as JSON. It can also be used to consume any third party XML (or any XML database like feeds)
and return us the response as JSON instead of XML. (We can convert the XML to JSON by using XMLtoJson
class provided.)
In this article, we try to learn how data can be "hosted" and "consumed" as JSON on cross domains.
2. Background
What Do I Mean by Json Proxy
Our JSON proxy here works in the same way as normal ASP.NET proxy pages which serves us data from any local or remote web-service. The only difference is, our JSON proxy
returns the data as a JSON object, thus it becomes easier for us to call our proxy as a normal JavaScript using the "<script src='out json proxy' />
" tag.
This enables us to use our proxy for cross domain requests (because JavaScript can be called from any remote site as well).
The only twist we introduce here is - we are writing these script tags dynamically. The "<script src="our json proxy" />
" tag
is generated at run-time and attached to our web-page's DOM (using the script attached). This enables us to pass the parameters to our proxy page and get dynamic response
on the basis of querystring.
What are Cross-Domain-Requests?
A cross domain request is a browser issue. It occurs when a web-page (coming from a website www.abcd.com) tries to access content from another website (www.xyz.com).
The browser treats it as a violation of "Same origin policy" and forces you to use the content from
the original website (www.abcd.com) only because your webpage comes from this site.
There are various workarounds suggested for Cross-Domain-Requests. The easiest one is to create a local proxy on website "www.abcd.com" which fetches the required
data from (www.xyz.com) and returns it to us as it is. Thus our web-pages located at (www.abcd.com) can use our local proxy page without violating "same origin policy"
and still getting data from the other website (www.xyz.com).
The problem occurs when we cannot create a proxy on www.abcd.com (like in the case if it is a static server). In such a case, we might have to extend our data portal
located at (www.xyz.com) to return us data as a JSON object. As JavaScript can be embedded from any location, our
JSON proxy - though it resides at server (www.xyz.com)
and still returns us the appropriate data to be used on our webpage at (www.abcd.com).
3. Description
The Server Side
As discussed earlier, our server side web page (JSON proxy) is an ASP.NET proxy to our data which we want to showcase. Only difference is - our JSON proxy returns
us JSON objects instead of XML as a web-service returns. We can also write a JSON web-service if we are using the same domain. For cross domain,
it becomes somewhat difficult to pass the parameters and invoke a web service. We are using dynamic script tags to handle cross domain requests.
Our JSON proxy resides at server. It fills data for us, either by loading from the database or by consuming any XML webservice or XML file database:
System.Collections.Generic.List<publication> returnList =
new System.Collections.Generic.List<publication>();
for (int tmp1 = 1; tmp1 <= 10; tmp1++)
{
if ((strSearch.ToUpper() == "ODD") && (tmp1 % 2 == 0))
continue;
else if ((strSearch.ToUpper() == "EVEN") && (tmp1 % 2 != 0))
continue;
returnList.Add(new publication(tmp1, "Author" + tmp1.ToString(),
"Title" + tmp1.ToString(), "Remarks" + tmp1.ToString(), "Category" +
tmp1.ToString(), "Link" + tmp1.ToString()));
}
Here is how we can use the above code to load an XML and return it as JSON.
XmlDocument docXml = new XmlDocument();
docXml.Load("someLocation");
returnStr = XmlToJson.XmlToJSON(docXml);
We use JavaScriptSerializer
to serialize our Business Objects list:
System.Web.Script.Serialization.JavaScriptSerializer ser =
new System.Web.Script.Serialization.JavaScriptSerializer();
returnStr = ser.Serialize(returnList);
The Client Side
Our client side HTML page has JavaScript code to create dynamic tags:
this.scriptObj = document.createElement("script");
this.scriptObj.setAttribute("type", "text/javascript");
this.scriptObj.setAttribute("charset", "utf-8");
this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
this.scriptObj.setAttribute("id", this.scriptId);
Script tag created above is added to the head
section of the page's DOM following function:
JSONscriptRequest.prototype.addScriptTag = function () {
this.headLoc.appendChild(this.scriptObj);
....
}
Then we attach our JSON handler function "parseData
" to the onload
event of our script. (Please note that this code
is different for Internet Explorer and other browsers. Appropriate scripts are collected from different blogs.)
this.scriptObj.onload= function() {parseData(jsonData);}
var scriptTag = document.getElementById(this.scriptId);
scriptTag.onreadystatechange = function () {
if ( scriptTag.readyState === "complete" ) {
parseData(jsonData);
scriptTag.onreadystatechange=null;
}}
4. Points of Interest
- This article uses:
- JSON and dynamic script tags from here
- Detects if the above script is loaded from here
XmlToJson
class comes from here
- jQuery traversal of JSON data from here
- Note:
- There is one
alert("loading...")
in the Internet Explorer code. Strange is the fact that once I insert the alert, the JavaScript gets the time
to load and display the JSON data correctly but removing the alert causes the JSON result to come as blank. Other than this, the code works fine.
5. History
I will try to update the code without having to use the "loading..." alert for Internet Explorer. I tried moving the scripts to the head but it didn't help.