ASP.NET: How to Emit and Consume JSON from ASMX Web Services

Many ASP.NET developers operate under the mistaken assumption that you need a WCF Service to handle JSON. Quite the contrary; ASMX services are happy to emit JSON. Here's how.

1. Add (or uncomment) the  [System.Web.Script.Services.ScriptService] attribute at the top of your ASMX service class:

[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {  ...

Requests to your service methods must meet two requirements:
2. Content-Type – The HTTP request must declare a content-type of 'application/json'. This tells the ScriptService that it will receive its parameters as JSON and that it should respond with JSON.
3. HTTP Method – By default, the HTTP request must be a POST request.

You simply add a Service Reference to your ASP.NET project that points to your service endpoint. The ASMX Service Reference is still there in Visual Studio 2010, and it will certainly be there in Visual Studio 11 as well:



I generally prefer to use ASMX services when possibly as they are more lightweight than WCF services and require far less configuration. They can also be considerably faster.

You can easily configure all the requirements at the client with the jQuery $ajax function. Here's a sample:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#submit").click(function () {
                var symbols = $("#sym").val();
                $.ajax({
                    type: "POST",
                    url: "./ASMXService.asmx/GetData",
                    data: "{'symbols': '" + symbols + "'}", //note the additional quotation marks!
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    cache: false,
                    success: AjaxSucceeded,
                    error: AjaxFailed
                });
            });
        });

        function AjaxSucceeded(result) {
            // debugger; // uncomment to debug
            BuildTable(result.d);
        }
        function AjaxFailed(result) {
            $('#quotes').html(result.status + ' ' + result.statusText);
        }

        function BuildTable(msg) {
            $("#quotes").empty();

            $('#quotesTemplate').tmpl(msg).appendTo('#quotes');
        }
      </script>  

    In this example solution, I've built a simple server-side method to get equity prices from Yahoo finance:

     public class ASMXService : System.Web.Services.WebService
    {
        private static readonly string url1 = "http://download.finance.yahoo.com/d/quotes.csv?s=";
        private static readonly string url2 = "&f=snkc6";

        [WebMethod]
        public List<Quote> GetData(string symbols)
        {
            var symbolString = symbols;
            var wc = new WebClient();
            string stuff = wc.DownloadString(url1 + symbolString + url2);
            wc.Dispose();
            string[] lines = stuff.Split("\r\n".ToCharArray());
            var quotes = new List<Quote>();
            foreach (string l in lines)
             {
                 if (l.Length < 2) continue;
                 // let's get rid of those quotation marks from Yahoo Finance
                string tmp = l.Replace('"', ' ');
                string[] toParse = tmp.Split(",".ToCharArray());
                var q = new Quote(toParse);
                 quotes.Add(q);
            }
            return quotes;
        }

And here is the Quote class:

public class Quote
    {
         public string Symbol { get; set; }
        public string Name { get; set; }
        public string LastTrade { get; set; }
         public string PercentChange { get; set; }

         public Quote() { }

        public Quote(string[] toParse)
        {
            try
            {
                 this.Symbol = toParse[0] ?? toParse[0];
                 this.Name = toParse[1] ?? toParse[1];
                 this.LastTrade = toParse[2] ?? toParse[2];
                 this.PercentChange = toParse[3] ?? toParse[3];
            }
            catch
            {
            }
        }
    }


The sample solution uses jQuery with the jQuery Templates script to generate a table of requested equity prices:




You can download the sample Visual Studio 2010 solution here.

By Peter Bromberg   Popularity  (7984 Views)