当json.js遇见dynamic.net烂尾篇

由于最近较忙,上一篇的坑估计要慢慢填了。感觉写文章介绍要比写程序还累啊。先看看测试程序,能够了解api支持哪些功能:

static void Main(string[] args)
{
//wrapper对象
dynamic data = DJson.Wrap(new
{
name
= "Jane",
male
= false,
age
= 24,
dob
= DateTime.Now,
friend
= new { name = "Jesse", male = true, age = 32, dob = DateTime.Now },
mobile
= new object[] { new[] { 86 }, 13888888888 },
});

Console.WriteLine(data.Stringfy());

//数组
data = new DJsonArray();
data[
0] = new { name = "小朋盂 1号" };
data[
1] = new { name = "小朋盂 2号" };
data[
2] = new { name = "小朋盂 3号" };

Console.WriteLine(data.Stringfy());

//反序列化
var json = data.Stringfy();
dynamic obj
= DJson.Parse(json);
//修改反序列化后的数据
obj[1] = new { name = "mike", age = 21, dob = DateTime.Now };
Console.WriteLine(obj.Stringfy());

//实际应用,将twitter statues反序列化
json = System.IO.File.ReadAllText("e:/twitter.js");
dynamic statuses
= DJson.Parse(json);
for (int i = 0; i < statuses.Length; i++)
{
var status
= statuses[i];
Console.WriteLine(
" id: {0}\nname: {1}\nfrom: {2}\ntext: {3}\n", status.user.id, status.user.name, status.user.location, status.text);
}

Console.ReadKey();
}

twitter文件请在这里下载

先放上代码,其实很简单,以后再慢慢分析

public class DJson : DynamicObject
{
protected Dictionary<string, object> _expando = new Dictionary<string, object>();
public override string ToString()
{
return this.Stringify();
}
public IEnumerable<string> Keys { get { return _expando.Keys; } }
public object this[string key] { get { return _expando[key]; } set { _expando[key] = value; } }

public DJson() { }

public static DJson Wrap(object obj)
{
if (!(obj is string) && (obj is IEnumerable) && !(obj is Dictionary<string, object>))
{
var array
= new DJsonArray();
int i = 0;
foreach (object v in obj as IEnumerable)
array[i
++] = DJson.Wrap(v);
return array;
}
else
{
var dj
= new DJson();
if (obj is Dictionary<string, object>)
{
foreach (var kv in obj as Dictionary<string, object>)
{
if (kv.Value == null)
dj[kv.Key]
= (object)null;
else if (IsPrimitive(kv.Value.GetType()))
dj[kv.Key]
= kv.Value;
else
dj[kv.Key]
= DJson.Wrap(kv.Value);
}
}
else
{
var t
= obj.GetType();
if (IsPrimitive(t))
throw new ArgumentException();
foreach (var p in t.GetProperties())
{
var v
= p.GetValue(obj, null);
if (IsPrimitive(p.PropertyType))
dj[p.Name]
= v;
else
dj[p.Name]
= DJson.Wrap(v);
}
}
return dj;
}
}

public static DJson Parse(string json)
{
var obj
= (new JavaScriptSerializer()).DeserializeObject(json);
return DJson.Wrap(obj);
}

public string Stringify()
{
var serializer
= new JavaScriptSerializer();
serializer.RegisterConverters(
new JavaScriptConverter[] { new DJsonConverter() });

if (this is DJsonArray)
return serializer.Serialize((this as DJsonArray).ToArray());

return serializer.Serialize(this);
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_expando.TryGetValue(binder.Name, out result))
return true;
return false;
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!(value is string) && (value is IEnumerable))
_expando[binder.Name]
= new DJsonArray(value as IEnumerable);
else
_expando[binder.Name]
= value;
return true;
}

internal static bool IsPrimitive(Type type)
{
return type.FullName.StartsWith("System.") && !type.FullName.StartsWith("System.Collection");
}
}

public class DJsonArray : DJson
{
Dictionary
<int, object> _array = new Dictionary<int, object>();
public object this[int index] { get { return _array[index]; } set { _array[index] = value; } }
public int Length { get { return _array.Keys.Count; } }

public DJsonArray() { }
public DJsonArray(IEnumerable array)
{
int i = 0;
foreach (var obj in array)
this[i++] = obj;
}

public object[] ToArray()
{
return _array.Values.ToArray();
}

public DJson ToObject()
{
var dj
= new DJson();
foreach (string key in _expando.Keys)
dj[key]
= _expando[key];
foreach (int key in _array.Keys)
dj[key.ToString()]
= _array[key];
return dj;
}
}

internal class DJsonConverter : JavaScriptConverter
{
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var dj
= (DJson)obj;

var result
= new Dictionary<string, object>();
foreach (string key in dj.Keys)
{
if (dj[key] is DJsonArray)
result[key]
= (dj[key] as DJsonArray).ToArray();
else
result[key]
= dj[key];
}

return result;
}

public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>(new Type[] { typeof(DJson), typeof(DJsonArray) }); }
}

public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
}

Newton的json库最近好像做了相同的事情,开始支持dynamic了

http://james.newtonking.com/archive/2011/01/03/json-net-4-0-release-1-net-4-and-windows-phone-support.aspx

posted @ 2011-02-27 18:39 dragonpig 阅读(...) 评论(...) 编辑 收藏