In this post I am going to walk through writing and consuming JSON services using ASP.Net, WCF, and jQuery to request the stock price for a company.
Visual Studio 2010 Web Application Project Template Additions
- jQuery Intellisense – let Visual Studio write your jQuery for you
- AJAX-enabled WCF Service – item template that auto-generates the web.config entries for configuring a JSON service to be consumed and proxied by an ASP.Net ScriptManager
- Targeted web.config files – easy way to manage different service endpoints for different environments
What is JSON?
Java Script Object Notation - JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
var dog = {color: "grey", name: "Spot", size: 46};
SOAP Bloat
SOAP services are extremely verbose. This verbosity enables us to use tools like Visual Studio’s built-in ”Add Service Reference” to auto-generate client proxy classes. The following examples demonstrate the XML that is used for requesting a stock price and the corresponding response:
Example SOAP Request
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.example.org/stock"> <m:GetStockPrice> <m:StockName>GOOG</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope>
Example SOAP Response
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.example.org/stock"> <m:GetStockPriceResponse> <m:Price>534.5</m:Price> </m:GetStockPriceResponse> </soap:Body> </soap:Envelope>
The above example when formatted as JSON is as follows:
GET Request
ticker=GOOG
JSON Response
{"d":534.5}
JSON Enabling a WCF Service
- Using the AJAX-enabled WCF Service item template pretty much does it all. An additional step can be taken to eliminate the need for the additions to the web.config by configuring the channel factory directly on the service declaration (.svc) file:
<%@ ServiceHost Language="C#" Debug="true" Service="Trentacular.JsonWcfDemo.StockPriceService" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" CodeBehind="StockPriceService.svc.cs" %>
- Decorate the operation (service method) with the WebGetAttribute to enable the use of HTTP GET for data retrieval and return the response as JSON :
[WebGet(ResponseFormat = WebMessageFormat.Json)]
Our resulting stock price service’s code behind will look like the following:
[ServiceContract(Namespace = JsonWcfDemoNamespace.Value)] public class StockPriceService { // To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json) // To create an operation that returns XML, // add [WebGet(ResponseFormat=WebMessageFormat.Xml)], // and include the following line in the operation body: // WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"; [OperationContract] [WebGet(ResponseFormat=WebMessageFormat.Json)] public StockPrice GetStockPrice(string ticker) { ... } // Add more operations here and mark them with [OperationContract] }
Converting Text to JSON and Back
eval() - invokes the JavaScript compiler. The compiler will correctly parse the text and produce an object structure. The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues.
JSON.parse() - To defend against security issues with the eval function, it is preferred to use a JSON parser. A JSON parser will recognize only JSON text, rejecting all scripts. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
jQuery’s $.getJSON() Method
jQuery provides the getJSON method for easily making calls to services providing JSON-formatted responses and performing the JSON conversion. Its signature is as follows:
$.getJSON( url, [ data ], [ callback(data, textStatus) ] )
url - A string containing the URL to which the request is sent.
data - A map or string that is sent to the server with the request.
callback(data, textStatus) - A callback function that is executed if the request succeeds.
Consuming our stock price service using the getJSON method will look like the following:
$.getJSON("StockPriceService.svc/GetStockPrice", { ticker: tickerValue }, function (data, textStatus) { if (textStatus != 'success' || !data.d) { $("#stockPricePanel") .html('<span class="error">Error looking up stock price. Did you enter a valid ticker?</span>'); } else { var stockPrice = data.d; var isIncrease = (stockPrice.Delta >= 0); var deltaStyle = isIncrease ? 'gain' : 'loss'; $("#stockPricePanel") .html('<span class="price">' + stockPrice.Price + '</span>') .append('<span class="delta ' + deltaStyle + '">' + stockPrice.Delta + '</span>') .append('<span class="percent ' + deltaStyle + '">(' + stockPrice.PercentChange + '%)</span>'); } });
Working with WCF Serialized JSON Dates
One caveat when working with JSON is that WCF serializes DateTimes to JSON in the format:
/Date({milliseconds since 01/01/1970}-{time zone})/

Unfortunately, native JSON conversion does not automatically convert the date string to a JavaScript date object. The following method shows an example of how to convert a JSON date string to a javascript Date object:
function convertJSONToDate(json) { return eval(json.replace(/\/Date\((.*?)\)\//gi, "new Date($1)")); }


Recent Comments