如何从JavaScriptSerializer生成的Object中提取信息

时间:2010-06-21 15:04:01

标签: c# json javascriptserializer

我正在用C#开发一个可以控制SqueezeboxServer(SBS)的应用程序。与SBS通信是通过JSON消息发送到http://serverIP:9000/jsonrpc.js 所以我通过HTTPWepRequest发送JSON消息,并通过HTTPWebResponse获得答案。

我得到的答案是JSON表示法中的String。这就是问题开始的地方......现在我将JSON消息转换为带有JavaScriptSerializer的Object。这是这样的:

public static Object FromJSON(this string reply)
{
    JavaScriptSerializer deSerializer = new JavaScriptSerializer();
    return deSerializer.DeserializeObject(reply);
}

这段代码给了我一个保存我要求的数据的对象。我要求的数据可能非常不同。有时候答案是单一答案,而在其他情况下,答案可能是多件事。

让我们考虑一下我所包含的两张图片:

第一个显示deSerializer返回后的对象。您可以看到该对象是一个包含4个键值对的Dictionary。我感兴趣的kvp是第四个。关键的“结果”是保存我需要的数据的结果。但是这把钥匙还有另一个Dictonary作为价值。这一直持续到我想要的实际数据,即专辑名称及其ID。

alt text http://www.freeimagehosting.net/uploads/865397a19e.jpg

在第二个图像中,我想要的数据是值0,它属于“_count”键。如您所见,此对象不那么复杂。

alt text http://www.freeimagehosting.net/uploads/f6feb27ab5.jpg

所以我的问题的底线是如何制作一个可以检索我想要的信息的解决方案,但是可以使用不同类型的对象(如在不同的深度中)?

希望任何人都可以向我发送正确的方向。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用JavaScriptConverter更好地控制反序列化体验。

        using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Web.UI.WebControls;
    using System.Collections;

    namespace System.Web.Script.Serialization.CS
    {
        public class ListItemCollectionConverter : JavaScriptConverter
        {

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

            public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
            {
                ListItemCollection listType = obj as ListItemCollection;

                if (listType != null)
                {
                    // Create the representation.
                    Dictionary<string, object> result = new Dictionary<string, object>();
                    ArrayList itemsList = new ArrayList();
                    foreach (ListItem item in listType)
                    {
                        //Add each entry to the dictionary.
                        Dictionary<string, object> listDict = new Dictionary<string, object>();
                        listDict.Add("Value", item.Value);
                        listDict.Add("Text", item.Text);
                        itemsList.Add(listDict);
                    }
                    result["List"] = itemsList;

                    return result;
                }
                return new Dictionary<string, object>();
            }

            public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
            {
                if (dictionary == null)
                    throw new ArgumentNullException("dictionary");

                if (type == typeof(ListItemCollection))
                {
                    // Create the instance to deserialize into.
                    ListItemCollection list = new ListItemCollection();

                    // Deserialize the ListItemCollection's items.
                    ArrayList itemsList = (ArrayList)dictionary["List"];
                    for (int i=0; i<itemsList.Count; i++)
                        list.Add(serializer.ConvertToType<ListItem>(itemsList[i]));

                    return list;
                }
                return null;
            }

        }
    }

然后反序列化

var serializer = new JavaScriptSerializer(); 
serialzer.RegisterConverters( new[]{ new DataObjectJavaScriptConverter() } ); 
var dataObj = serializer.Deserialize<DataObject>( json ); 

JavaScriptSerializer.Deserialize - how to change field names