How To Create A JSON Web Service In ASP.NET

ASP.NET makes it easy to create web services but they usually return XML. Like many web developers I now prefer JSON. This article and sample code will show you how to get your web service to return data in the JSON format. The web service is written in C#. Since my web hosting company only provides me with a MySQL database, we’ll make this project a little more challenging by pulling data from a MySQL database. Finally, I will show you how to use jQuery to call your web service. So you get three kinds of value from this article; a web service in C# to return JSON data, how to use a MySQL database, and how to call an ASP.NET web service using jQuery. None of those three tasks are very intuitive or simple when using ASP.NET because they all go against the framework conventions.

The first task to tackle is connecting to the MySQL database. ASP.NET is usually used with SQL Server or SQL Server Express so using MySQL is not always easy. On my local development web server I downloaded the MySQL Connector/ODBC 5.1 from http://dev.mysql.com/downloads/connector/odbc/5.1.html. Then my web.config file merely needed a connection string node:

   1: <connectionStrings>
   2:         <add name="Books" connectionString="Driver={MySQL ODBC 5.1 Driver};Server=localhost;Database=books;uid=root;pwd=password;option=3;" providerName="System.Data.Odbc"/>
   3: </connectionStrings>

NOTE: This is not my real password and there is no external access to MySQL server running on my development server.

For this demonstration, I am using a simple database I use to keep track of the books I read. It has a single table “reading” which has only three columns; BookNum, Title, Author. I don’t know if CrystalTech has the MySQL ODBC driver installed, but I was able to create a datasource name using the control panel so the connection string used a “dsn=books” instead of the driver.

The C# code for the web service at http://www.williamsportwebdeveloper.com/BookServices.asmx shows you how an ODBC connection is used to query the MySQL database. What you should notice in the code is that various method attributes are used on the web service class and methods. These method attributes require the System.Web.Script reference. If you get an error concerning missing assemblies then make sure your web.config file has everything it needs for an AJAX enabled ASP.NET site. As you can see, there is a ScriptMethod method attribute that specifies JSON as the response format. The tricky part is converting a dataset into a JSON string. I used a jagged array to accomplish that because it will serialize properly. That is probably the most valuable tip in this entire article.

   1: using System;
   2: using System.Web;
   3: using System.Collections;
   4: using System.Web.Services;
   5: using System.Web.Services.Protocols;
   6: using System.Data;
   7: using System.Data.Odbc;
   8: using System.Web.Script.Serialization;
   9: using System.Web.Script.Services;
  10:
  11: /// <summary>
  12: /// Web services to query the book database. All methods return JSON data.
  13: /// </summary>
  14: [WebService(Description = "Web services to query the book database.", Namespace = "http://www.williamsportwebdeveloper.com/")]
  15: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  16: [ScriptService]
  17: public class BookServices : System.Web.Services.WebService {
  18:
  19:     public BookServices () {
  20:
  21:         //Uncomment the following line if using designed components 
  22:         //InitializeComponent(); 
  23:     }
  24:
  25:     [WebMethod(Description = "Gets the books matching part of a title.")]
  26:     [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
  27:     public string GetBooksByTitle(string strTitle) {
  28:         OdbcConnection objConnection = new OdbcConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Books"].ConnectionString);
  29:         OdbcCommand objCommand = new OdbcCommand("SELECT * FROM reading WHERE Title LIKE '%" + strTitle + "%' ORDER BY BookNum;", objConnection);
  30:         DataSet objDataSet = new DataSet();
  31:         OdbcDataAdapter objDataAdapter = new OdbcDataAdapter(objCommand);
  32:         objDataAdapter.Fill(objDataSet, "reading");
  33:         objConnection.Close();
  34:
  35:         // Create a multidimensional jagged array
  36:         string[][] JaggedArray = new string[objDataSet.Tables[0].Rows.Count][];
  37:         int i = 0;
  38:         foreach (DataRow rs in objDataSet.Tables[0].Rows)
  39:         {
  40:             JaggedArray[i] = new string[] { rs["BookNum"].ToString(), rs["Title"].ToString(), rs["Author"].ToString() };
  41:             i = i + 1;
  42:         }
  43:
  44:         // Return JSON data
  45:         JavaScriptSerializer js = new JavaScriptSerializer();
  46:         string strJSON = js.Serialize(JaggedArray);
  47:         return strJSON;
  48:     }
  49:
  50:     [WebMethod(Description = "Gets the books matching part of an author's name.")]
  51:     [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
  52:     public string GetBooksByAuthor(string strAuthor)
  53:     {
  54:         OdbcConnection objConnection = new OdbcConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Books"].ConnectionString);
  55:         OdbcCommand objCommand = new OdbcCommand("SELECT * FROM reading WHERE Author LIKE '%" + strAuthor + "%' ORDER BY BookNum;", objConnection);
  56:         DataSet objDataSet = new DataSet();
  57:         OdbcDataAdapter objDataAdapter = new OdbcDataAdapter(objCommand);
  58:         objDataAdapter.Fill(objDataSet, "reading");
  59:         objConnection.Close();
  60:
  61:         // Create a multidimensional jagged array
  62:         string[][] JaggedArray = new string[objDataSet.Tables[0].Rows.Count][];
  63:         int i = 0;
  64:         foreach (DataRow rs in objDataSet.Tables[0].Rows)
  65:         {
  66:             JaggedArray[i] = new string[] { rs["BookNum"].ToString(), rs["Title"].ToString(), rs["Author"].ToString() };
  67:             i = i + 1;
  68:         }
  69:
  70:         // Return JSON data
  71:         JavaScriptSerializer js = new JavaScriptSerializer();
  72:         string strJSON = js.Serialize(JaggedArray);
  73:         return strJSON;
  74:     }
  75:
  76: }

At this point you have a web service that queries a MySQL database and returns records as JSON data. This is extremely useful if you want to use that data on your home page without making it an ASP.NET page. You can get the data using AJAX and avoid having your home page show an error should your ASP.NET web application develop a problem. Next I will show you the JavaScript code for calling the web service. I’ll use the jQuery library because it is extremely popular with web developers right now. It makes it easy to write JavaScript that works in both browsers but you may not know how to call an ASP.NET web service using jQuery, especially since we need to pass a parameter to the web service methods. This is also tricky because the content type must be JSON.

   1: $(document).ready(function() {
   2:     $("#btnTitleQuery").bind("click", function() {
   3:         $("#query_results").empty();
   4:         $("#query_results").append('<table id="ResultsTable" class="BooksTable"><tr><th>BookNum</th><th>Title</th><th>Author</th></tr>');
   5:         $.ajax({
   6:             type: "POST",
   7:             contentType: "application/json; charset=utf-8",
   8:             url: "BookServices.asmx/GetBooksByTitle",
   9:             data: '{ strTitle: "' + $("#txtTitle").val() + '" }',
  10:             dataType: "json",
  11:             success: function(msg) {
  12:                 var c = eval(msg.d);
  13:                 for (var i in c) {
  14:                     $("#ResultsTable tr:last").after("<tr><td>" + c[i][0] + "</td><td>" + c[i][1] + "</td><td>" + c[i][2] + "</td></tr>");
  15:                 }
  16:             }
  17:         });
  18:     })
  19:     $("#btnAuthorQuery").bind("click", function() {
  20:         $("#query_results").empty();
  21:         $("#query_results").append('<table id="ResultsTable" class="BooksTable"><tr><th>BookNum</th><th>Title</th><th>Author</th></tr>');
  22:         $.ajax({
  23:             type: "POST",
  24:             contentType: "application/json; charset=utf-8",
  25:             url: "BookServices.asmx/GetBooksByAuthor",
  26:             data: '{ strAuthor: "' + $("#txtAuthor").val() + '" }',
  27:             dataType: "json",
  28:             success: function(msg) {
  29:                 var c = eval(msg.d);
  30:                 for (var i in c) {
  31:                     $("#ResultsTable tr:last").after("<tr><td>" + c[i][0] + "</td><td>" + c[i][1] + "</td><td>" + c[i][2] + "</td></tr>");
  32:                 }
  33:             }
  34:         });
  35:     })
  36: });

You can try a working example at: http://www.williamsportwebdeveloper.com/BookQuery.html. This JavaScript is binding function prototypes to the button click events. These functions call the web service methods using the POST method and pass the required parameters as JSON data. The JSON data that it receives in response is used to create a table. You can continue to issue queries without reloading the web page. If you view the source of the BookQuery.html page you will find all the code required for the client page because it does not require any server side code.

This entry was posted in ASP.NET, Databases, JavaScript, Programming, Web and tagged , , , , , . Bookmark the permalink.