我们在程序中经常需要对一个Object做序列化操作,有时希望对特别的属性,标记特别的名称。有几种方法可以实现:

1. 使用JSON.NET类库

    这是一个开源的类库,您可以从这里下载。它支持格式化,自定义等功能。我们通常在需要序列化属性下标记即可:

        [JsonProperty(Name = "text")]
        public string Text { get; set; }

    这个属性最后序列化的名字是text.

2. 在.net 4.0 也提供一个DataMember特性类似它,你可能在WCF中有看到过:

        [DataMember(Name = "text")] 
        public string Text { get; set; }

    后面发现JSON.NET它也支持这个特性。

下面我们来看一个TreeItem的Object,为了演出这里同时支持两种方法,当然你可选择其中一种。

   1:      [DataContract] 
   2:      public class TreeItem<TValue> : ITreeNode<TreeItem<TValue>, TValue>
   3:      {
   4:          private readonly List<TreeItem<TValue>> children = new List<TreeItem<TValue>>();
   5:   
   6:          /// <summary>
   7:          /// Gets or sets the id.
   8:          /// </summary>
   9:          /// <value>The id.</value>
  10:          /// <remarks>type must be string,because Jquery tree will use it replace method on it</remarks>
  11:          [DataMember(Name = "id")] 
  12:          public string Id { get; set; }
  13:   
  14:   
  15:          /// <summary>
  16:          /// Gets or sets a value indicating whether this <see cref="TreeItem"/> is showcheck.
  17:          /// </summary>
  18:          /// <value><c>true</c> if showcheck; otherwise, <c>false</c>.</value>
  19:          [DataMember(Name = "showcheck")] 
  20:          public bool Showcheck { set; get; }
  21:   
  22:   
  23:          /// <summary>
  24:          /// Gets or sets a value indicating whether this <see cref="TreeItem"/> is isexpand.
  25:          /// </summary>
  26:          /// <value><c>true</c> if isexpand; otherwise, <c>false</c>.</value>
  27:          [DataMember(Name = "isexpand")] 
  28:          public bool Isexpand { set; get; }
  29:   
  30:   
  31:          /// <summary>
  32:          /// Gets or sets the checkstate.
  33:          /// </summary>
  34:          /// <value>The checkstate.</value>
  35:         [DataMember(Name = "checkstate")] 
  36:          public int Checkstate { get; set; }
  37:   
  38:          /// <summary>
  39:          ///  whether load complete(indicating whether async load data)
  40:          ///  Suppose sync load data to node should be true
  41:          /// </summary>
  42:          /// <value><c>true</c> if complete; otherwise, <c>false</c>.</value>
  43:          
  44:          [DataMember(Name = "complete")]
  45:          public bool Complete { get; set; }
  46:   
  47:          private bool _haschild;
  48:          /// <summary>
  49:          /// Gets a value indicating whether this instance has children.
  50:          /// </summary>
  51:          /// <value>
  52:          ///     <c>true</c> if this instance has children; otherwise, <c>false</c>.
  53:          /// </value>
  54:          [DataMember(Name = "hasChildren")]
  55:          public bool HasChildren
  56:          {
  57:              get { return (Children != null && Children.Count() > 0); }
  58:              set { _haschild=value;}
  59:          }
  60:   
  61:          #region ITreeNode<TreeItem<TValue>,TValue> Members
  62:   
  63:          /// <summary>
  64:          /// Gets or sets the text.
  65:          /// </summary>
  66:          /// <value>The text.</value>
  67:          [DataMember(Name = "text")] 
  68:          public string Text { get; set; }
  69:   
  70:   
  71:          /// <summary>
  72:          /// Gets or sets the value.
  73:          /// </summary>
  74:          /// <value>The value.</value>
  75:          [DataMember(Name = "value")] 
  76:          public TValue Value { get; set; }
  77:   
  78:          /// <summary>
  79:          /// Gets or sets the parent.
  80:          /// </summary>
  81:          /// <value>The parent.</value>
  82:          public TreeItem<TValue> Parent { get; set; }
  83:   
  84:   
  85:          /// <summary>
  86:          /// Gets the children.
  87:          /// </summary>
  88:          /// <value>The children.</value>
  89:          [JsonProperty("ChildNodes")]
  90:          [DataMember(Name = "ChildNodes")] 
  91:          public IEnumerable<TreeItem<TValue>> Children
  92:          {
  93:              get { return children; }
  94:          }
  95:   
  96:          #endregion
  97:      }

然后用扩展方法,封装一下JSON.NET的方法:

   1:          public static string ToJsonString<TValue>(this TreeItem<TValue> treeItem)
   2:          {
   3:              string sJson = JsonConvert.SerializeObject(
   4:               treeItem);
   5:              return "var treedata=[" + sJson + "];";
   6:          }
   7:   
   8:          public static string ToFormatJsonString<TValue>(this TreeItem<TValue> treeItem)
   9:          {
  10:              string sJson = JsonConvert.SerializeObject(
  11:                  treeItem
  12:                 , Formatting.Indented,
  13:                  new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
  14:                  );
  15:              return "var treedata=[" + sJson + "];";
  16:          }

下面是TestMethod:

   1:          public void TestDataContractJsonSerializer()
   2:          {
   3:              var treeitem = new TreeItem<string>();
   4:              treeitem.Id = "1";
   5:              treeitem.Text = "Root";
   6:              treeitem.Value = "3223";
   7:              treeitem.Isexpand = true;
   8:              treeitem.Showcheck = true;
   9:              treeitem.Add(new TreeItem<string>() { Id ="2", Text = "Node2", Value = "9982",Showcheck=true,Isexpand=true,Checkstate=1 });
  10:   
  11:              using (MemoryStream stream1 = new MemoryStream())
  12:              {
  13:   
  14:                  var ser = new DataContractJsonSerializer(typeof(TreeItem<string>));
  15:                  ser.WriteObject(stream1, treeitem);
  16:                  stream1.Position = 0;
  17:                  StreamReader sr = new StreamReader(stream1);
  18:   
  19:                  string mstr = "var treedata=[" + sr.ReadToEnd() + "];";
  20:   
  21:                  Console.WriteLine(mstr);
  22:   
  23:                  string tstr = treeitem.ToJsonString<string>();
  24:                  Console.WriteLine(tstr);
  25:   
  26:                  Assert.AreEqual(tstr.Length, mstr.Length);
  27:              }
  28:          }

最后这个UnitTest通过了,输出结果如下:

   1:  var treedata=[{"ChildNodes":[{"ChildNodes":[],"checkstate":1,"complete":true,"hasChildren":false,"id":"2","isexpand":true,"showcheck":true,"text":"Node2","value":"9982"}],"checkstate":0,"complete":true,"hasChildren":true,"id":"1","isexpand":true,"showcheck":true,"text":"Root","value":"3223"}];
   2:  var treedata=[{"id":"1","showcheck":true,"isexpand":true,"checkstate":0,"complete":true,"hasChildren":true,"text":"Root","value":"3223","ChildNodes":[{"id":"2","showcheck":true,"isexpand":true,"checkstate":1,"complete":true,"hasChildren":false,"text":"Node2","value":"9982","ChildNodes":[]}]}];
   3:   
   4:  1 passed, 0 failed, 0 skipped, took 0.86 seconds (MSTest 10.0).

你会发现它们之间区别是,顺序不同。如果您不希望引用第三方的类库,可以使用.net 4.0 提供的DataContractJsonSerializer 类。

希望对您的开发有帮助。


作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog

posted on 2011-01-27 21:13  PetterLiu  阅读(5914)  评论(2编辑  收藏  举报