Streamlining the JSON Serialization

By James at November 01, 2007 03:26
Filed Under: Web Development, Ajax and Javascript

For a while now I have been using the Newtwonsoft.Json dll to generate my JSON objects. The documentation is pretty sparse and I had to do a lot of experimentation to figure out the best way to do it. I ended up with this base code.

myUCR_DepartmentsTableAdapters.MyUCR_DepartmentsTableAdapter deptTA = new myUCR_DepartmentsTableAdapters.MyUCR_DepartmentsTableAdapter();
myUCR_Departments.MyUCR_DepartmentsDataTable deptDT = new myUCR_Departments.MyUCR_DepartmentsDataTable();
deptTA.FillDepts(deptDT);
StringWriter sw = new StringWriter();
JsonWriter writer = new JsonWriter(sw);
writer.WriteStartArray();

foreach (myUCR_Departments.MyUCR_DepartmentsRow deptRow in deptDT)
{
   writer.WriteStartObject();
   writer.WritePropertyName("deptID"); writer.WriteValue(deptRow.deptID.ToString());
   writer.WritePropertyName("dept"); writer.WriteValue(deptRow.department.ToString().Trim());
   writer.WriteEndObject();           
}
writer.WriteEndArray();
writer.Flush();
Response.Write(sw.GetStringBuilder().ToString());

 As you can see, that's a lot of code to serialize a simple datatable.

I wanted to find an easier way, so started browsing around. Googling for "JSON DataTable Serialization", I came across this article "A DataTable Serializer for ASP.NET AJAX" at denydotnet.com. What he did was to extend the JavaScriptConverter found in System.Web.Script.Serialization to serialize a DataTable. I looked through his code and decided to implement it.

Now here's how I do my serialization:

        MyUCR_LoginTableAdapter ta = new MyUCR_LoginTableAdapter();
        DataTable dt = ta.GetByTesting();
        JavaScriptSerializer toJSON = new JavaScriptSerializer();
        toJSON.RegisterConverters(new JavaScriptConverter[]{new JavaScriptDataTableConverter()});
        Response.Write(toJSON.Serialize(dt));

And what rocks is the object names are mapped to the column names in the database.

Cool

James

 

Comments (4) -

5/27/2008 9:46:10 PM #

Kishore

Hi James,

Could you please let me know how can we use the returned data from the maethod in the javascript code.What is the best way to populate them into a HTML table.

Regards,
Kishore.

Kishore | Reply

5/28/2008 1:07:05 AM #

James Johnson

Hi Kishore,
The data returned is in JSON format, so I have a function which converts the JSON formatted string to an Array.

function returnJson(rText)
{
    if(rText.indexOf(chk) > -1){rText = rText.substring(chk.length, rText.length);}
    var func = new Function("return " + rText);
    var jsonObj = func();
    return jsonObj;
}

After that it's just a matter of looping through the elements of the array and processing them. For instance:

var myString = jsonObj[i]["myString"];
Creating a table isn't difficult, just loop through the array, creating a row for each iteration, and a cell for each value in the that row.

Take a look at my "Home Grown Ajax presentation". And check out json.org for more information on the JSON format.

Thanks for the comment,
James

James Johnson | Reply

1/23/2009 1:51:52 AM #

Fredericke

Hi,

Can you include the JavaScriptDataTableConverter() function?  I've been trying to locate the original article at dennydotnet.com but it seems the website is currently down.

Thanks.

Fredericke | Reply

1/23/2009 2:53:50 AM #

James

here you go....

using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Web;
//using System.Web.
using System.Web.Script.Serialization;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


/// <summary>
/// Summary description for JavaScriptDataTableConverter
/// </summary>
///
public class JavaScriptDataTableConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException("Deserialize is not implemented.");
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        DataTable dt = obj as DataTable;
        Dictionary<string, object> result = new Dictionary<string, object>();

        if (dt != null && dt.Rows.Count > 0)
        {
            // List for row values
            List<object> rowValues = new List<object>();

            foreach (DataRow dr in dt.Rows)
            {
                // Dictionary for col name / col value
                Dictionary<string, object> colValues = new Dictionary<string, object>();

                foreach (DataColumn dc in dt.Columns)
                {
                    colValues.Add(dc.ColumnName, // col name
                     (string.Empty == dr[dc].ToString()) ? null : dr[dc]); // col value
                }

                // Add values to row
                rowValues.Add(colValues);
            }

            // Add rows to serialized object
            result["rows"] = rowValues;
        }

        return result;
    }

    public override IEnumerable<Type> SupportedTypes
    {
        //Define the DataTable as a supported type.
        get
        {
            return new System.Collections.ObjectModel.ReadOnlyCollection<Type>(
             new List<Type>(
              new Type[] { typeof(DataTable) }
             )
            );
        }
    }
}


James | Reply

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


About the author

James James is a five time and current Microsoft MVP in Client App Development, a Telerik Insider, a past Director on the INETA North America Board, a husband and dad, and has been developing software since the early days of Laser Discs and HyperCard stacks. As the Founder and President of the Inland Empire .NET User's Group, he has fondly watched it grow from a twice-a-month, early Saturday morning group of five in 2003, to a robust and rambunctious gathering of all types and sizes of .NET developers.

James loves to dig deep into the latest cutting edge technologies - sometimes with spectacular disasters - and spread the word about the latest and greatest bits, getting people excited about developing web sites and applications on the .NET platform, and using the best tools for the job. He tries to blog as often as he can, but usually gets distracted by EF, LINQ, MVC, ASP, SQL, XML, and most other types of acronyms. To keep calm James plays a mean Djembe and tries to practice his violin. You can follow him on twitter at @latringo.

And as usual, the comments, suggestions, writings and rants are my own, and really shouldn't reflect the opinions of my employer. That is, unless it really does.

James Twitter Feed

Recent Comments

Comment RSS

Month List