不考虑 JSON 数据格式有错误的情况下,可以试试以下函数。
public string Writer(Object obj)
{
System.Text.StringBuilder builder = new StringBuilder();
try
{
if(obj is String||obj is ValueType) return String.Format("{0}",obj);
System.Type type = obj.GetType();
if(obj is System.Collections.IList)
{
builder.Append(IListToJson(obj as System.Collections.IList));
}
else
{
if(type.IsClass&&!type.IsValueType&&!type.IsEnum)
{
builder.Append(ObjectToJson(obj,type.GetProperties()));
}
}
return builder.ToString();
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
builder = null;
}
}
private String ObjectToJson(Object obj,System.Reflection.PropertyInfo[] properties)
{
System.Text.StringBuilder builder = new StringBuilder();
try
{
foreach(System.Reflection.PropertyInfo property in properties)
{
if(property.CanRead)
{
String key = property.Name;
Object val = property.GetValue(obj,null);
if(null!=val)
{
builder.AppendFormat(",\"{0}\":",key);
if(val is String||val is ValueType)
{
if(val is String || val is Char)
{
if(val is Char&&val.Equals(Char.MinValue)) builder.AppendFormat("\"\"");
else builder.AppendFormat("\"{0}\"",val);
}
else
{
builder.Append(val.ToString().ToLower());
}
}
else
{
System.Type type = val.GetType();
if(val is System.Collections.IList)
{
builder.Append(IListToJson(val as System.Collections.IList));
}
else
{
if(type.IsClass&&!type.IsValueType&&!type.IsEnum)
{
builder.Append(ObjectToJson(val,type.GetProperties()));
}
}
}
}
}
}
return builder.Replace(",","{",0,1) .Append("}").ToString();
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
builder = null;
}
}
private String IListToJson(System.Collections.IList list)
{
System.Text.StringBuilder builder = new StringBuilder();
try
{
System.Collections.IEnumerator enumerator = list.GetEnumerator();
while(enumerator.MoveNext())
{
Object val = enumerator.Current;
if(null==val)
{
builder.Append(",null");
}
else
{
if(val is String||val is ValueType)
{
if(val is String || val is Char)
{
if(val is Char&&val.Equals(Char.MinValue)) builder.AppendFormat(",\"\"");
else builder.AppendFormat(",\"{0}\"",val);
}
else
{
builder.AppendFormat(",{0}",val.ToString().ToLower());
}
}
else
{
System.Type type = val.GetType();
if(val is System.Collections.IList)
{
builder.AppendFormat(",{0}",IListToJson(val as System.Collections.IList));
}
else
{
if(type.IsClass&&!type.IsValueType&&!type.IsEnum)
{
builder.AppendFormat(",{0}",ObjectToJson(val,type.GetProperties()));
}
}
}
}
}
if(0==builder.Length) return builder.Append("[]").ToString();
return builder.Replace(",","[",0,1) .Append("]").ToString();
}
catch(System.Exception ex)
{
throw ex;
}
finally
{
builder = null;
}
}
public Object Reader(String json)
{
if('{'.Equals(json[0])) return JsonToObject(json);
else if('['.Equals(json[0])) return JsonToIList(json);
else return null;
}
private System.Collections.Hashtable JsonToObject(String json)
{
System.Collections.Hashtable hashTable = new Hashtable();
System.Text.StringBuilder builder = new System.Text.StringBuilder(json);
System.Text.RegularExpressions.Match keyMatch = null;
do
{
keyMatch = System.Text.RegularExpressions.Regex.Match(builder.ToString(),@"(?<!\\)\""(?=:):");
if(keyMatch.Success)
{
Int32 index = 0;
String key = builder.ToString(2,keyMatch.Index-2);
String val = String.Empty;
Int32 jsonType=0;
switch(builder[keyMatch.Index+keyMatch.Length])
{
case '"':
{
for(Int32 i = keyMatch.Index+keyMatch.Length+1;;i++)
{
if('"'==builder[i])
{
if('\\'!=builder[i-1])
{
index = i;
break;
}
}
}
val = builder.ToString(keyMatch.Index+keyMatch.Length+1,index-(keyMatch.Index+keyMatch.Length+1));
jsonType = 1;
builder.Remove(0,index+1);
break;
}
case '[':
{
for(Int32 i = keyMatch.Index+keyMatch.Length+1;;i++)
{
if(']'==builder[i])
{
val = builder.ToString(keyMatch.Index+keyMatch.Length,i-(keyMatch.Index+keyMatch.Length)+1);
System.Text.RegularExpressions.MatchCollection matchesStart = System.Text.RegularExpressions.Regex.Matches(val,@"\[");
System.Text.RegularExpressions.MatchCollection matchesEnd = System.Text.RegularExpressions.Regex.Matches(val,@"\]");
if(matchesStart.Count==matchesEnd.Count)
{
index = i;
break;
}
}
}
jsonType = 2;
builder.Remove(0,index+1);
break;
}
case '{':
{
for(Int32 i = keyMatch.Index+keyMatch.Length+1;;i++)
{
if('}'==builder[i])
{
val = builder.ToString(keyMatch.Index+keyMatch.Length,i-(keyMatch.Index+keyMatch.Length)+1);
System.Text.RegularExpressions.MatchCollection matchesStart = System.Text.RegularExpressions.Regex.Matches(val,@"\{");
System.Text.RegularExpressions.MatchCollection matchesEnd = System.Text.RegularExpressions.Regex.Matches(val,@"\}");
if(matchesStart.Count==matchesEnd.Count)
{
index = i;
break;
}
}
}
jsonType = 3;
builder.Remove(0,index+1);
break;
}
default:
{
for(Int32 i = keyMatch.Index+keyMatch.Length+1;;i++)
{
if(','==builder[i])
{
index = i;
break;
}
}
val = builder.ToString(keyMatch.Index+keyMatch.Length,index-(keyMatch.Index+keyMatch.Length));
builder.Remove(0,index);
break;
}
}
switch(jsonType)
{
case 0:
{
if(System.Text.RegularExpressions.Regex.IsMatch(val,@"true|false",System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
hashTable.Add(key,Convert.ToBoolean(val));
}
else
{
hashTable.Add(key,Convert.ToDecimal(val));
}
break;
}
case 2:
{
hashTable.Add(key,JsonToIList(val.ToString()));
break;
}
case 3:
{
hashTable.Add(key,JsonToObject(val.ToString()));
break;
}
default:
{
hashTable.Add(key,val);
break;
}
}
}
}while(keyMatch.Success);
return hashTable;
}
private System.Collections.ArrayList JsonToIList(String json)
{
System.Collections.ArrayList arrayList = new ArrayList();
if("[]".Equals(json)) return arrayList;
System.Text.StringBuilder builder = new System.Text.StringBuilder(json);
for(Int32 i=1;i<builder.Length;)
{
Int32 index = 0;
String val = String.Empty;
Int32 jsonType=0;
switch(builder[i])
{
case '"':
{
for(Int32 j = i+1;j<builder.Length;j++)
{
if('"'==builder[j])
{
if('\\'!=builder[j-1])
{
index = j;
break;
}
}
}
val = builder.ToString(i+1,index-(i+1));
jsonType = 1;
break;
}
case '[':
{
for(Int32 j = i+1;j<builder.Length;j++)
{
if(']'==builder[j])
{
val = builder.ToString(i,j-i+1);
System.Text.RegularExpressions.MatchCollection matchesStart = System.Text.RegularExpressions.Regex.Matches(val,@"\[");
System.Text.RegularExpressions.MatchCollection matchesEnd = System.Text.RegularExpressions.Regex.Matches(val,@"\]");
if(matchesStart.Count==matchesEnd.Count)
{
index = j;
break;
}
}
}
jsonType = 2;
break;
}
case '{':
{
for(Int32 j = i+1;j<builder.Length;j++)
{
if('}'==builder[j])
{
val = builder.ToString(i,j-i+1);
System.Text.RegularExpressions.MatchCollection matchesStart = System.Text.RegularExpressions.Regex.Matches(val,@"\{");
System.Text.RegularExpressions.MatchCollection matchesEnd = System.Text.RegularExpressions.Regex.Matches(val,@"\}");
if(matchesStart.Count==matchesEnd.Count)
{
index = j;
break;
}
}
}
jsonType = 3;
break;
}
default:
{
for(Int32 j = i+1;j<builder.Length;j++)
{
if(','==builder[j]||']'==builder[j])
{
index = j;
break;
}
}
val = builder.ToString(i,index-i);
break;
}
}
if(0==jsonType)i=index+1;
else i=index+2;
switch(jsonType)
{
case 0:
{
if("null".Equals(val))
{
arrayList.Add(null);
}
else
{
if(System.Text.RegularExpressions.Regex.IsMatch(val,@"true|false",System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
arrayList.Add(Convert.ToBoolean(val));
}
else
{
arrayList.Add(Convert.ToDecimal(val));
}
}
break;
}
case 2:
{
arrayList.Add(JsonToIList(val.ToString()));
break;
}
case 3:
{
arrayList.Add(JsonToObject(val.ToString()));
break;
}
default:
{
arrayList.Add(val);
break;
}
}
}
return arrayList;
}
public void Reader(String json,Object model)
{
if(null==model) return;
Object obj = Reader(json);
System.Type type = model.GetType();
if(obj is System.Collections.ArrayList&&model is System.Collections.IList)
{
Reader(obj as System.Collections.ArrayList, model);
}
else if(obj is System.Collections.Hashtable&&type.IsClass&&!type.IsValueType&&!type.IsEnum)
{
Reader(obj as System.Collections.Hashtable, model);
}
}
private void Reader(System.Collections.Hashtable hashTable, Object model)
{
System.Type type = model.GetType();
System.Collections.IDictionaryEnumerator enumerator = hashTable.GetEnumerator();
while(enumerator.MoveNext())
{
String key = enumerator.Key as String;
System.Reflection.PropertyInfo property = type.GetProperty(key);
if(property.CanWrite)
{
if(enumerator.Value is Decimal||enumerator.Value is Boolean||enumerator.Value is String)
{
if(property.PropertyType.IsValueType&&enumerator.Value is String)
{
if(String.Empty.Equals(enumerator.Value)) property.SetValue(model,System.Char.MinValue,null);
else property.SetValue(model,Convert.ChangeType(enumerator.Value,property.PropertyType) ,null);
}
else
{
property.SetValue(model,Convert.ChangeType(enumerator.Value,property.PropertyType) ,null);
}
}
else if(enumerator.Value is System.Collections.IList)
{
Object arrayObject = null;
if(property.PropertyType.IsArray) arrayObject = System.Array.CreateInstance(property.PropertyType.GetElementType(),(enumerator.Value as System.Collections.IList).Count);
else arrayObject = System.Activator.CreateInstance(property.PropertyType);
Reader(enumerator.Value as System.Collections.ArrayList, arrayObject);
property.SetValue(model,arrayObject,null);
}
else
{
Object modelObject = System.Activator.CreateInstance(property.PropertyType);
Reader(enumerator.Value as System.Collections.Hashtable, modelObject);
property.SetValue(model,modelObject,null);
}
}
}
}
private void Reader(System.Collections.ArrayList arrayList, Object model)
{
System.Type type = model.GetType();
System.Collections.IList iList = model as System.Collections.IList;
if(type.IsArray)
{
System.Type typeValue = type.GetElementType();
if(typeValue.IsValueType||"String".Equals(typeValue.Name))
{
for(int i=0;i<arrayList.Count;i++)
{
iList[i]= Convert.ChangeType(arrayList[i], typeValue);
}
}
else
{
for(int i=0;i<arrayList.Count;i++)
{
Object modelValue = System.Activator.CreateInstance(typeValue);
Reader(arrayList[i] as Hashtable,modelValue);
iList[i]=Convert.ChangeType(modelValue, typeValue);
}
}
}
else
{
for(int i=0;i<arrayList.Count;i++)
{
iList[i]=arrayList[i];
}
}
}