浅析ASP.NET万能JSON解析器

  概念介绍

  还是先简单说说Json的一些例子吧。注意,以下概念是我自己定义的,可以参考.net里面的TYPE的模型设计

  如果有争议,欢迎提出来探讨!

  1.最简单:

  {"total":0}

  total就是值,值是数值,等于0

  2. 复杂点

  {"total":0,"data":{"377149574" : 1}}

  total是值,data是对象,这个对象包含了"377149574"这个值,等于1

  3. 最复杂

  {"total":0,"data":{"377149574":[{"cid":"377149574"}]}}

  total是值,data是对象,377149574是数组,这个数组包含了一些列的对象,例如{"cid":"377149574"}这个对象。

  有了以上的概念,就可以设计出通用的json模型了。

  万能JSON源码:

  

复制代码 代码如下:

  using System;

  using System.Collections.Generic;

  using System.Text;

  namespace Pixysoft.Json

  {

  public class CommonJsonModelAnalyzer

  {

  protected string _GetKey(string rawjson)

  {

  if (string.IsNullOrEmpty(rawjson))

  return rawjson;

  rawjson = rawjson.Trim();

  string[] jsons = rawjson.Split(new char[] { ':' });

  if (jsons.Length < 2)

  return rawjson;

  return jsons[0].Replace("\"", "").Trim();

  }

  protected string _GetValue(string rawjson)

  {

  if (string.IsNullOrEmpty(rawjson))

  return rawjson;

  rawjson = rawjson.Trim();

  string[] jsons = rawjson.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

  if (jsons.Length < 2)

  return rawjson;

  StringBuilder builder = new StringBuilder();

  for (int i = 1; i < jsons.Length; i++)

  {

  builder.Append(jsons[i]);

  builder.Append(":");

  }

  if (builder.Length > 0)

  builder.Remove(builder.Length - 1, 1);

  string value = builder.ToString();

  if (value.StartsWith("\""))

  value = value.Substring(1);

  if (value.EndsWith("\""))

  value = value.Substring(0, value.Length - 1);

  return value;

  }

  protected List<string> _GetCollection(string rawjson)

  {

  //[{},{}]

  List<string> list = new List<string>();

  if (string.IsNullOrEmpty(rawjson))

  return list;

  rawjson = rawjson.Trim();

  StringBuilder builder = new StringBuilder();

  int nestlevel = -1;

  int mnestlevel = -1;

  for (int i = 0; i < rawjson.Length; i++)

  {

  if (i == 0)

  continue;

  else if (i == rawjson.Length - 1)

  continue;

  char jsonchar = rawjson[i];

  if (jsonchar == '{')

  {

  nestlevel++;

  }

  if (jsonchar == '}')

  {

  nestlevel--;

  }

  if (jsonchar == '[')

  {

  mnestlevel++;

  }

  if (jsonchar == ']')

  {

  mnestlevel--;

  }

  if (jsonchar == ',' && nestlevel == -1 && mnestlevel == -1)

  {

  list.Add(builder.ToString());

  builder = new StringBuilder();

  }

  else

  {

  builder.Append(jsonchar);

  }

  }

  if (builder.Length > 0)

  list.Add(builder.ToString());

  return list;

  }

  }

  }

  

复制代码 代码如下:

  using System;

  using System.Collections.Generic;

  using System.Text;

  namespace Pixysoft.Json

  {

  public class CommonJsonModel : CommonJsonModelAnalyzer

  {

  private string rawjson;

  private bool isValue = false;

  private bool isModel = false;

  private bool isCollection = false;

  internal CommonJsonModel(string rawjson)

  {

  this.rawjson = rawjson;

  if (string.IsNullOrEmpty(rawjson))

  throw new Exception("missing rawjson");

  rawjson = rawjson.Trim();

  if (rawjson.StartsWith("{"))

  {

  isModel = true;

  }

  else if (rawjson.StartsWith("["))

  {

  isCollection = true;

  }

  else

  {

  isValue = true;

  }

  }

  public string Rawjson

  {

  get { return rawjson; }

  }

  public bool IsValue()

  {

  return isValue;

  }

  public bool IsValue(string key)

  {

  if (!isModel)

  return false;

  if (string.IsNullOrEmpty(key))

  return false;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  {

  CommonJsonModel submodel = new CommonJsonModel(model.Value);

  return submodel.IsValue();

  }

  }

  return false;

  }

  public bool IsModel()

  {

  return isModel;

  }

  public bool IsModel(string key)

  {

  if (!isModel)

  return false;

  if (string.IsNullOrEmpty(key))

  return false;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  {

  CommonJsonModel submodel = new CommonJsonModel(model.Value);

  return submodel.IsModel();

  }

  }

  return false;

  }

  public bool IsCollection()

  {

  return isCollection;

  }

  public bool IsCollection(string key)

  {

  if (!isModel)

  return false;

  if (string.IsNullOrEmpty(key))

  return false;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  {

  CommonJsonModel submodel = new CommonJsonModel(model.Value);

  return submodel.IsCollection();

  }

  }

  return false;

  }

  /// <summary>

  /// 当模型是对象,返回拥有的key

  /// </summary>

  /// <returns></returns>

  public List<string> GetKeys()

  {

  if (!isModel)

  return null;

  List<string> list = new List<string>();

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  string key = new CommonJsonModel(subjson).Key;

  if (!string.IsNullOrEmpty(key))

  list.Add(key);

  }

  return list;

  }

  /// <summary>

  /// 当模型是对象,key对应是值,则返回key对应的值

  /// </summary>

  /// <param name="key"></param>

  /// <returns></returns>

  public string GetValue(string key)

  {

  if (!isModel)

  return null;

  if (string.IsNullOrEmpty(key))

  return null;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  return model.Value;

  }

  return null;

  }

  /// <summary>

  /// 模型是对象,key对应是对象,返回key对应的对象

  /// </summary>

  /// <param name="key"></param>

  /// <returns></returns>

  public CommonJsonModel GetModel(string key)

  {

  if (!isModel)

  return null;

  if (string.IsNullOrEmpty(key))

  return null;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  {

  CommonJsonModel submodel = new CommonJsonModel(model.Value);

  if (!submodel.IsModel())

  return null;

  else

  return submodel;

  }

  }

  return null;

  }

  /// <summary>

  /// 模型是对象,key对应是集合,返回集合

  /// </summary>

  /// <param name="key"></param>

  /// <returns></returns>

  public CommonJsonModel GetCollection(string key)

  {

  if (!isModel)

  return null;

  if (string.IsNullOrEmpty(key))

  return null;

  foreach (string subjson in base._GetCollection(this.rawjson))

  {

  CommonJsonModel model = new CommonJsonModel(subjson);

  if (!model.IsValue())

  continue;

  if (model.Key == key)

  {

  CommonJsonModel submodel = new CommonJsonModel(model.Value);

  if (!submodel.IsCollection())

  return null;

  else

  return submodel;

  }

  }

  return null;

  }

  /// <summary>

  /// 模型是集合,返回自身

  /// </summary>

  /// <returns></returns>

  public List<CommonJsonModel> GetCollection()

  {

  List<CommonJsonModel> list = new List<CommonJsonModel>();

  if (IsValue())

  return list;

  foreach (string subjson in base._GetCollection(rawjson))

  {

  list.Add(new CommonJsonModel(subjson));

  }

  return list;

  }

  /// <summary>

  /// 当模型是值对象,返回key

  /// </summary>

  private string Key

  {

  get

  {

  if (IsValue())

  return base._GetKey(rawjson);

  return null;

  }

  }

  /// <summary>

  /// 当模型是值对象,返回value

  /// </summary>

  private string Value

  {

  get

  {

  if (!IsValue())

  return null;

  return base._GetValue(rawjson);

  }

  }

  }

  }

  使用方法

  public CommonJsonModel DeSerialize(string json)

  {

  return new CommonJsonModel(json);

  }

  超级简单,只要new一个通用对象,把json字符串放进去就行了。

  针对上文的3个例子,我给出3种使用方法:

  {"total":0}

  CommonJsonModel model = DeSerialize(json);

  model.GetValue("total") // return 0

  {"total":0,"data":{"377149574" : 1}}

  CommonJsonModel model = DeSerialize(json);

  model.GetModel("data").GetValue("377149574") //return 1

  {"total":0,"data":{"377149574":[{"cid":"377149574"}]}}

  CommonJsonModel model = DeSerialize(json);

  model.GetCollection("377149574").GetCollection()[0].GetValue("cid") //return 377149574

  这个有点点复杂,

  1. 首先377149574代表了一个集合,所以要用model.GetCollection("377149574")把这个集合取出来。

  2. 其次这个集合里面包含了很多对象,因此用GetColllection()把这些对象取出来

  3. 在这些对象List里面取第一个[0],表示取了":{"cid":"377149574"}这个对象,然后再用GetValue("cid")把对象的值取出来。