1. Introduction

  • This tutorial is supposed to serve dual purpose
    • 1. To demonstrate an Asp.Net Json Proxy which pulls data from database(or xml file/web-service) and serves it as JSON and
    • 2. 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 how JSON web service can be consumed using jQuery/javascript AJAX. This is a better approach for intra domain JSON requests.
    • 1. Our JSON web service returns us the data as JSON/XML on the basis of Content Type we request from it.
    • 2. 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 server and can be consumed locally using 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 serve us data from any local or remote web-service. 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 javascripts can be called from any remote site as well).

The only twist we introduce here is - we are writing thes 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? 

Cross domain request is a browser issue. It occurs when any of our 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 voilation of "Same origin policy" and forces you to use the content from original website (www.abcd.com) only because your webpage comes from this site.

cross1.jpg
There are various workarounds suggested for Cross-Domain-Requests. 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 voilating "same origin policy" and still getting data from the other website (www.xyz.com).

cross2.jpg

Problem occurse 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 Json object. As javascript can be embedded from any location, our json proxy - though it resides at server (www.xyz.com) still returns us appropriate data to be used on our webpage ate (www.abcd.com).

cross3.jpg

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 />();

        //This is our data access method. Supposed to fill our publication list from database
        //We fill it using the below for loop for simplicity.
        for (int tmp1 = 1; tmp1 <= 10; tmp1++)
        {
            //Some customized data - according to query string.
            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.

        //For Example
        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:-

// Create the script tag
    this.scriptObj = document.createElement("script");
    
    // Add script object attributes
    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 IE and other browsers. Appropriate scripts are collected from different blogs.)
 //Here I am adding the script to onload event:-
this.scriptObj.onload= function() {parseData(jsonData);}
//and
var scriptTag = document.getElementById(this.scriptId);
scriptTag.onreadystatechange  =  function () {
        if ( scriptTag.readyState === "complete" ) {
          		  parseData(jsonData);
          		  // Avoid memory leaks (and duplicate call to callback) in IE
          			scriptTag.onreadystatechange=null;
		  }//end if
}//end function;

4. Points of Interest

  • This article is using
    • -JSON and dynamic script tags from here.
    • -Detect if 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 IE 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

Will try to update the code without having to use the "loading..." alert for IE. I tried moving the scripts to the head but it didn't help.
推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架