JSON String with objects

Jul 29, 2009 at 7:08 PM

Ok, I'm trying to deseralize this string into meaningful object(s):

{"action":"Router","method":"Navigate","data":["dashboard",null],"type":"rpc","tid":2}

I have an object that I'm trying to deserialize it into which has action, method, data, type, and tid as properties.  However, right now "data" is of type object[] in my class.  This works fine when its just a list of simple objects like strings, null, etc. But, if I have a data that looks like this:

,"data":["dashboard",{"id", 1, "teststring", "test"}]

where one of the items is a JSON object, then it all breaks down.  The embedded JSON object just turns into an "object" type and has no data on it that I can see. (or if it does, its not usable)

What do I do in this case?  Do I need to write my own custom handler?  Does JObject factor into this here?  I could probably writing my own handler to turn it into a complex Dictionary<string, object> type I suppose, but I wanted to find out if there was an easier, built in way to handle these - or if I'm going about it wrong.

Thanks

D

Jul 29, 2009 at 8:07 PM

I ended up just putting together my own converter.  Here's the code if someone else wants it - but let me know if there was an easier way.

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;

namespace Ext.Direct
{
    internal class ComplexDataConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            if (objectType == typeof(object[])) { return true; }
            return false;
        }

        public override object ReadJson(JsonReader reader, Type objectType)
        {
            ArrayList output = new ArrayList();

            if (reader.TokenType == JsonToken.Null) { return null; }

            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.StartObject)
                {
                    output.Add(ReadObject(reader));                   
                }
                else if (reader.TokenType == JsonToken.EndArray)
                {
                    return output.ToArray();
                }
                else
                {
                    output.Add(reader.Value);
                }
            }

            return output.ToArray();
        }

        private object ReadObject(JsonReader reader)
        {
            Dictionary<string, object> subobject = new Dictionary<string, object>();
            string currentKey = null;

            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.EndObject)
                {
                    return subobject;
                }
                else if (currentKey == null)
                {
                    currentKey = reader.Value.ToString();
                }
                else
                {
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        subobject.Add(currentKey, ReadObject(reader));
                    }
                    else
                    {
                        subobject.Add(currentKey, reader.Value);
                    }
                    currentKey = null;
                }
            }
            return null;
        }

        public override void WriteJson(JsonWriter writer, object value)
        {
            throw new NotImplementedException();
        }
    }
}

Coordinator
Jul 31, 2009 at 11:12 AM

I've changed the serializer so that if the type that is being deserialized to is object then complex JSON structures (objects, arrays) will be deserialized as JObject/JArray.

Jul 31, 2009 at 11:59 AM

You did that just now?  Or did I do something wrong and not call it properly?

Thanks James!

 

Coordinator
Aug 1, 2009 at 1:24 AM

I had checked the source code into CodePlex. Download and build it and it should work.

Check out ComplexValuesInObjectArray in JsonSerializerTests if you want to see an example.

Sep 1, 2009 at 4:32 AM

help me!

I encountered a problem,

 

using Newtonsoft.Json;

.............................................

public partial Class Test : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DataTable dt = GetDataTable();
            string jsonstring = SerializeJSON(dt);
            DataTable dt2 = null;
            if (!string.IsNullOrEmpty(jsonstring))
            {
                Response.Write("<script>alert('" + jsonstring + "')</script>");
                dt2 = (DataTable)DeserializeJSON(jsonstring, typeof(DataTable));
            }
        }
    }
   
    public string SerializeJSON(object obj)
    {
        if (obj != null)
            return Newtonsoft.Json.JavaScriptConvert.SerializeObject(obj);
        else
            return "";
    }
 
    public object DeserializeJSON(string str, Type type)
    {
        return Newtonsoft.Json.JavaScriptConvert.DeserializeObject(str,type);      
    }
   
    public DataTable GetDataTable()
    {      
           DataTable dt=new DataTable();
           dt.Columns.Add("ID",typeof(System.Int32));
           dt.Columns.Add("Name",typeof(System.String));
           dt.Columns.Add("Alias", typeof(System.String));          
            for(int i=0;i<=3;i++)
            {
                DataRow dr=dt.NewRow();
                dr[0] = i;
                dr[1] = "Name As Good" + i;
                dr[2] = "g" + i;
                dt.Rows.Add(dr);
            }
            return dt;
    }

}

 

why i use JSON Deserialize DataTable throw a  exception

JsonSerializationException: Self referencing loop

but i new a Entity class , it's ok.

Look forward to your reply!

my email-address is ruonanxiao@gmail.com

thanks!