[.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) JSON序列化利器 Newtonsoft.Json 及 通用Json类

[.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) JSON序列化利器 Newtonsoft.Json 及 通用Json类

本节导读:

关于JSON序列化,不能不了解Json.net(Newtonsoft.Json)这款世界级的开源类库,除了拥有良好的性能之外,功能也是非常强大的。

本节会详细说明这个类库。此外,对于不喜欢使用第三方类库的同学,会整理一个基于微软类库的通用Json类。

读前必备:

本节主要介绍一款第三方类库和一个自己整理封装的类库,说起到封装就想到.NET面向对象三大特性。有需要的朋友可以参考下面三篇。

A.封装  [.net 面向对象编程基础]  (11) 面向对象三大特性——封装 

B.继承  [.net 面向对象编程基础]  (12) 面向对象三大特性——继承 

C.多态  [.net 面向对象编程基础]  (13) 面向对象三大特性——多态 

1. 第三方类库Newtonsoft.Json

1.1  和.NET自带类库比较

目前使用的三种JSON序列化和类库主要有:

A. DataContractJsonSerializer (微软自带类库)

B. JavaScriptSerializer (微软自带类库)

C.Json.net 即Newtonsoft.Json (第三方开源Json类型)

就性能而言,DataContractJsonSerializer 和 Newtonsoft.Json差距不大,JavaScriptSerializer 性能略差一些。

下图是一张来自Newtonsoft.net官方的性能测试图表。

功能方面,当然不用说Newtonsoft.net是专家做Json的开源库,自然功能强大一些。下面会将Newtonsoft.net一些比较实用的功能介绍一下。

1.2  Newtonsoft.net简介

最新版本:7.01 截止我发布本篇文章时

官方地址:https://github.com/JamesNK/Newtonsoft.Json/releases

我提供一个下载:http://files.cnblogs.com/files/yubinfeng/Newtonsoft.Json7.0.1-.net4.0.rar

在打包的时候,为每个版本的.net都有一个dll,这上传是即于最高版本.net4.0版本的。

官方提供的下载在国内真是相当的慢。

1.3 常用序列化DataTable、DataSet、Entity

三个使用方法都相似,我以DataSet为例介绍:

使用前在项目中引用,这个就不用多说了

//创建 DataTable 1
DataTable dt1 = new DataTable("Top") ;

dt1.Columns.AddRange(new DataColumn[]{
    new DataColumn { ColumnName = "Name", DataType = typeof(System.String) },
    new DataColumn { ColumnName = "Age", DataType = typeof(System.Int32) },
    new DataColumn { ColumnName = "MenPai", DataType = typeof(System.String) }
});

dt1.Rows.Add(new object[]{"周伯通", 22,"重阳宫" });
dt1.Rows.Add(new object[]{"洪七公", 19,"丐帮" });
dt1.Rows.Add(new object[]{"黄药师",55,"桃花岛" });
dt1.Rows.Add(new object[]{"欧阳锋",49,"白驼山" });           

//创建 DataTable 2
DataTable dt2 = dt1.Clone();
dt2.TableName = "Second";
dt2.Rows.Add(new object[]{"郭靖",22,"丐帮"});
dt2.Rows.Add(new object[]{"黄蓉",19,"丐帮"});
dt2.Rows.Add(new object[]{ "梅超风", 55,"桃花岛"});
dt2.Rows.Add(new object[]{ "杨康", 49,"金"});

//创建DataSet
DataSet ds = new DataSet("Master");
ds.Tables.AddRange(new DataTable[]{ dt1,dt2});

//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(ds);
Console.WriteLine(myJsonStr);

运行结果如下 :

下面将上面生成的字符串myJsonStr反序列化为DataSet

//DataSet反序列化
DataSet newDs = JsonConvert.DeserializeObject<DataSet>(myJsonStr);
foreach(DataTable Ds in newDs.Tables)
{
    Console.WriteLine(Ds.TableName + "\n");
    foreach (DataRow dr in Ds.Rows)
    {
        foreach (DataColumn dc in Ds.Columns)
            Console.Write(dc.ColumnName + ":"+dr[dc] +"   ");
        Console.WriteLine("\n");
    }
}

运行结果如下:

1.4  Newtonsoft.net 特殊处理功能

上面的示例展示了 Newtonsoft.net基本序列化和反序列化,那么能不能像DataContractJsonSerializerg 一样只处理标记的实体类属性或字段呢,答案是肯定可以。在特殊处理能力上,Newtonsoft.net非常强大,下面举例说明几种:

A.设置序列化模式

序列化模式上有两种:

OptOut:除外模式;默认表示序列化所有成员,如果某些成员不想序列化,在类成员上加上标记[JsonIgnore],当然类也要标记序列模式[JsonObject(MemberSerialization.OptOut)]

OptIn:包含模式; 默认表示不序列化所有成员,如果某些成员想序列化,可以在类成员上标记[JsonProperty],同样的,需要在类上也标记序列模式 [JsonObject(MemberSerialization.OptIn)]

下面示例 说明:

先创建类“武林高手”

/// <summary>
/// 类:武林高手
/// MartialArtsMaster
/// </summary>
[JsonObject(MemberSerialization.OptOut)]
public class MartialArtsMaster
{
    [JsonIgnore]
    /// <summary>
    /// 编号
    /// </summary>
    public int id { get; set; }

    /// <summary>
    /// 姓名
    /// </summary>
    public string name { get; set; }

    /// <summary>
    /// 门派
    /// </summary>
    public string menpai { get; set; }
    [JsonIgnore]
    /// <summary>
    /// 武功
    /// </summary>
    public string kongFu { get; set; }

}

添加数据并序列化:

//增加几个武林高手
List<MartialArtsMaster> masterList = new List<MartialArtsMaster>() {
    new MartialArtsMaster(){ id=1, name="段誉", menpai="天龙寺", kongFu="六脉神剑"},
    new MartialArtsMaster(){ id=2, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
    new MartialArtsMaster(){ id=3, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList);
Console.WriteLine(myJsonStr);

运行结果如下:

下面看一下包含模式(OptIn):

类及成员标识如下:

/// <summary>
/// 类:武林高手
/// MartialArtsMaster
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
public class MartialArtsMaster
{

    /// <summary>
    /// 编号
    /// </summary>
    public int id { get; set; }
     [JsonProperty]
    /// <summary>
    /// 姓名
    /// </summary>
    public string name { get; set; }

    [JsonProperty]
    /// <summary>
    /// 门派
    /// </summary>
    public string menpai { get; set; }

    /// <summary>
    /// 武功
    /// </summary>
    public string kongFu { get; set; }

}

序列化:

//增加几个武林高手
List<MartialArtsMaster> masterList = new List<MartialArtsMaster>() {
    new MartialArtsMaster(){ id=1, name="段誉", menpai="天龙寺", kongFu="六脉神剑"},
    new MartialArtsMaster(){ id=2, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
    new MartialArtsMaster(){ id=3, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList);
Console.WriteLine(myJsonStr);

运行结果如果如下:

B.处理默认值 

类库对实体带默认值的成员是否序列化?情况有两种处理机制:

序列化和反序列化时,忽略默认值  DefaultValueHandling.Ignore

序列化和反序列化时,包含默认值  DefaultValueHandling.Include

需要注意两点:

一是,定义属性默认值,需要引用命名空间using System.ComponentModel;

二是,Formatting.Indented枚举表示输出的JSON是有缩进处理。

C.处理空值

空值 使用 JsonSerializerSettings.NullValueHandling 设置

空值也是有两个开关:

不序列空值 NullValueHandling.Ignore

序列化空值(默认)NullValueHandling.Include

//增加几个武林高手
List<MartialArtsMaster> masterList = new List<MartialArtsMaster>() {
new MartialArtsMaster(){ id=1, name="段誉", menpai="天龙寺"},
new MartialArtsMaster(){ id=2, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
new MartialArtsMaster(){ id=3, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//设置默认处理项
JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
jsonSettings.NullValueHandling = NullValueHandling.Ignore;

//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList,Formatting.Indented,jsonSettings);
Console.WriteLine(myJsonStr);

运行结果如下:

D.处理非公有成员

(这一点DataContractJsonSerializerg 只支持公有,而Newtonsoft.Json可以支持 序列化私有成员)

处理方法:只需要在私有成员上面加标识["JsonProperty"],就可以了。

 [JsonProperty]
 private string gongFu{ get; set; }

E.处理日期 

对于日期处理也是这套类库比较强大的地方,提供了转换类IsoDateTimeConverter来完成对日期的处理。

先定继承两个类,重写来处理两种日期格式,然后在实体类中标记

 public class MyDateTimeConverter : DateTimeConverterBase
        {
            private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd hh-mm-ss" };

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                dtConverter.WriteJson(writer, value, serializer);
            }
        }
        public class MyCnDateTimeConverter : DateTimeConverterBase
        {
            private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy年MM月d日 hh时mm分ss秒" };

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                dtConverter.WriteJson(writer, value, serializer);
            }
        }
        //// <summary>
        /// 类:武林高手
        /// MartialArtsMaster
        /// </summary>

        public class MartialArtsMaster
        {

            /// <summary>
            /// 编号
            /// </summary>
            public int id { get; set; }

            /// <summary>
            /// 姓名
            /// </summary>
            public string name { get; set; }

            /// <summary>
            /// 出道时间
            /// </summary>
           [ JsonConverter(typeof(MyCnDateTimeConverter))]
            public  DateTime DebutTime { get; set; }

            /// <summary>
            /// 生日
            /// </summary>
            [JsonConverter(typeof(MyDateTimeConverter))]
            public DateTime Birthday { get; set; }

        }

序列化:

//日期转换
//增加几个武林高手
List<MartialArtsMaster> masterList = new List<MartialArtsMaster>() {
new MartialArtsMaster(){ id=1, name="段誉", Birthday=new DateTime(1982,2,12,10,53,10)},
new MartialArtsMaster(){ id=2, name="乔峰", Birthday=new DateTime(1982,2,12)},
new MartialArtsMaster(){ id=3, name="虚竹",  Birthday=new DateTime(1982,2,12),  DebutTime=new DateTime(1982,2,12)}
};

//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList,Formatting.Indented);
Console.WriteLine(myJsonStr);

运行结果如下:

F.自定义成员名 

我们在序列化时,不想使用属性或字段的名字,可以完成改名。

改名在属性上加如下标记,即可:

[JsonProperty(PropertyName = "名字")]

G.动态成员清单 

对于不同的序列化,我们需要的属性或字段如果不同,还可以通过清单来动态完成。

Newtonsoft.Json的功能远不止这些,更加详细的使用,可以参考官方网站的示例有100多个,还有详细的API文档

URL:http://www.newtonsoft.com/json/help/html/SerializationSettings.htm

2.  JSON通用类

对于不想使用第三方类库的小伙伴,我整理一个JSON序列化的类库,即于微软自带的序列化类。

命名空间:KaJiMao.Common

类名:JsonHelper

文件名:JsonHelper.cs

  1 using System;
  2 using System.Data;
  3 using System.Text;
  4 using System.Collections.Generic;
  5 using System.Reflection;
  6 using System.Data.Common;
  7 using System.Collections;
  8 using System.IO;
  9 using System.Text.RegularExpressions;
 10 using System.Runtime.Serialization.Json;
 11
 12
 13 namespace KaJiMao.Common
 14 {
 15     /// <summary>
 16     /// Json通用类
 17     /// Yubinfeng
 18     /// Date:2015/07/11
 19
 20     public static class JsonHepler
 21     {
 22         #region List序列化为 Json 字符串
 23         /// <summary>
 24         /// List序列化为 Json 字符串
 25         /// </summary>
 26         /// <typeparam name="T"></typeparam>
 27         /// <param name="jsonName"></param>
 28         /// <param name="list"></param>
 29         /// <returns></returns>
 30         public static string ListToJson<T>(IList<T> list, string jsonName)
 31         {
 32             StringBuilder Json = new StringBuilder();
 33             if (string.IsNullOrEmpty(jsonName))
 34                 jsonName = list[0].GetType().Name;
 35             Json.Append("{\"" + jsonName + "\":[");
 36             if (list.Count > 0)
 37             {
 38                 for (int i = 0; i < list.Count; i++)
 39                 {
 40                     T obj = Activator.CreateInstance<T>();
 41                     PropertyInfo[] pi = obj.GetType().GetProperties();
 42                     Json.Append("{");
 43                     for (int j = 0; j < pi.Length; j++)
 44                     {
 45                         Type type;
 46                         object o = pi[j].GetValue(list[i], null);
 47                         string v = string.Empty;
 48                         if (o != null)
 49                         {
 50                             type = o.GetType();
 51                             v = o.ToString();
 52                         }
 53                         else
 54                         {
 55                             type = typeof(string);
 56                         }
 57
 58                         Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(v, type));
 59
 60                         if (j < pi.Length - 1)
 61                         {
 62                             Json.Append(",");
 63                         }
 64                     }
 65                     Json.Append("}");
 66                     if (i < list.Count - 1)
 67                     {
 68                         Json.Append(",");
 69                     }
 70                 }
 71             }
 72             Json.Append("]}");
 73             return Json.ToString();
 74         }
 75         #endregion
 76
 77         #region 序列化集合对象
 78         /// <summary>
 79         /// 序列化集合对象
 80           /// </summary>
 81         public static string JsonSerializerByArrayData<T>(T[] tArray)
 82         {
 83             DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T[]));
 84             MemoryStream ms = new MemoryStream();
 85             ser.WriteObject(ms, tArray);
 86             string jsonString = Encoding.UTF8.GetString(ms.ToArray());
 87             ms.Close();
 88             string p = @"\\/Date\((\d+)\+\d+\)\\/";
 89             MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
 90             Regex reg = new Regex(p);
 91             jsonString = reg.Replace(jsonString, matchEvaluator);
 92             return jsonString;
 93         }
 94         #endregion
 95
 96         #region 序列化单个对象
 97         /// <summary>
 98         /// 序列化单个对象
 99         /// </summary>
100         public static string JsonSerializerBySingleData<T>(T t)
101         {
102             DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
103             MemoryStream ms = new MemoryStream();
104             ser.WriteObject(ms, t);
105             string jsonString = Encoding.UTF8.GetString(ms.ToArray());
106             ms.Close();
107             string p = @"\\/Date\((\d+)\+\d+\)\\/";
108             MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
109             Regex reg = new Regex(p);
110             jsonString = reg.Replace(jsonString, matchEvaluator);
111             return jsonString;
112         }
113         #endregion
114
115         #region 反序列化单个对象
116         /// <summary>
117         /// 反序列化单个对象
118          /// </summary>
119         public static T JsonDeserializeBySingleData<T>(string jsonString)
120         {
121             //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式 
122             string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
123             MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
124             Regex reg = new Regex(p);
125             jsonString = reg.Replace(jsonString, matchEvaluator);
126             DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
127             MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
128             T obj = (T)ser.ReadObject(ms);
129             return obj;
130         }
131         #endregion
132
133         #region 反序列化集合对象
134         /// <summary>
135          /// 反序列化集合对象
136         /// </summary>
137         public static T[] JsonDeserializeByArrayData<T>(string jsonString)
138         {
139             //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式 
140             string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
141             MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
142             Regex reg = new Regex(p);
143             jsonString = reg.Replace(jsonString, matchEvaluator);
144             DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T[]));
145             MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
146             T[] arrayObj = (T[])ser.ReadObject(ms);
147             return arrayObj;
148         }
149         #endregion
150
151         #region 将Json序列化时间转为字符串 ("yyyy-MM-dd HH:mm:ss")
152         /// <summary>
153          /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串
154          /// </summary>
155         private static string ConvertJsonDateToDateString(Match m)
156         {
157             string result = string.Empty;
158             DateTime dt = new DateTime(1970, 1, 1);
159             dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
160             dt = dt.ToLocalTime();
161             result = dt.ToString("yyyy-MM-dd HH:mm:ss");
162             return result;
163         }
164         #endregion
165
166         #region 将时间字符串转为Json时间
167         /// <summary> 
168          /// 将时间字符串转为Json时间
169         /// </summary>
170         private static string ConvertDateStringToJsonDate(Match m)
171         {
172             string result = string.Empty;
173             DateTime dt = DateTime.Parse(m.Groups[0].Value);
174             dt = dt.ToUniversalTime();
175             TimeSpan ts = dt - DateTime.Parse("1970-01-01");
176             result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
177             return result;
178         }
179         #endregion
180
181         #region ist转成json
182         /// <summary>
183          /// List转成json
184          /// </summary>
185          /// <typeparam name="T"></typeparam>
186           /// <param name="list"></param>
187          /// <returns></returns>
188         public static string ListToJson<T>(IList<T> list)
189         {
190             object obj = list[0];
191             return ListToJson<T>(list, obj.GetType().Name);
192         }
193         #endregion
194
195         #region 对象转换为Json字符串
196         /// <summary>
197         /// 对象转换为Json字符串
198         /// </summary>
199         /// <param name="jsonObject">对象</param>
200         /// <returns>Json字符串</returns>
201         public static string ToJson(object jsonObject)
202         {
203             try
204             {
205                 StringBuilder jsonString = new StringBuilder();
206                 jsonString.Append("{");
207                 PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties();
208                 for (int i = 0; i < propertyInfo.Length; i++)
209                 {
210                     object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null);
211                     if (objectValue == null)
212                     {
213                         continue;
214                     }
215                     StringBuilder value = new StringBuilder();
216                     if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan)
217                     {
218                         value.Append("\"" + objectValue.ToString() + "\"");
219                     }
220                     else if (objectValue is string)
221                     {
222                         value.Append("\"" + objectValue.ToString() + "\"");
223                     }
224                     else if (objectValue is IEnumerable)
225                     {
226                         value.Append(ToJson((IEnumerable)objectValue));
227                     }
228                     else
229                     {
230                         value.Append("\"" + objectValue.ToString() + "\"");
231                     }
232                     jsonString.Append("\"" + propertyInfo[i].Name + "\":" + value + ","); ;
233                 }
234                 return jsonString.ToString().TrimEnd(‘,‘) + "}";
235             }
236             catch (Exception ex)
237             {
238                 throw ex;
239             }
240         }
241         #endregion
242
243         #region 对象集合转换Json
244         /// <summary>
245          /// 对象集合转换Json
246          /// </summary>
247          /// <param name="array">集合对象</param>
248          /// <returns>Json字符串</returns>
249         public static string ToJson(IEnumerable array)
250         {
251             string jsonString = "[";
252             foreach (object item in array)
253             {
254                 jsonString += ToJson(item) + ",";
255             }
256             if (jsonString.Length > 1)
257             {
258                 jsonString.Remove(jsonString.Length - 1, jsonString.Length);
259             }
260             else
261             {
262                 jsonString = "[]";
263             }
264             return jsonString + "]";
265         }
266         #endregion
267
268         #region 普通集合转换Json
269         /// <summary>
270         /// 普通集合转换Json
271          /// </summary>
272         /// <param name="array">集合对象</param>
273         /// <returns>Json字符串</returns>
274         public static string ToArrayString(IEnumerable array)
275         {
276             string jsonString = "[";
277             foreach (object item in array)
278             {
279                 jsonString = ToJson(item.ToString()) + ",";
280             }
281             jsonString.Remove(jsonString.Length - 1, jsonString.Length);
282             return jsonString + "]";
283         }
284         #endregion
285
286         #region Datatable转换为Json
287         /// <summary>
288          /// Datatable转换为Json
289         /// </summary>
290         /// <param name="table">Datatable对象</param>
291          /// <returns>Json字符串</returns>
292         public static string ToJson(DataTable dt)
293         {
294             StringBuilder jsonString = new StringBuilder();
295             jsonString.Append("[");
296             DataRowCollection drc = dt.Rows;
297             for (int i = 0; i < drc.Count; i++)
298             {
299                 jsonString.Append("{");
300                 for (int j = 0; j < dt.Columns.Count; j++)
301                 {
302                     string strKey = dt.Columns[j].ColumnName;
303                     string strValue = drc[i][j].ToString();
304                     Type type = dt.Columns[j].DataType;
305                     jsonString.Append("\"" + strKey + "\":");
306                     strValue = StringFormat(strValue, type);
307                     if (j < dt.Columns.Count - 1)
308                     {
309                         jsonString.Append(strValue + ",");
310                     }
311                     else
312                     {
313                         jsonString.Append(strValue);
314                     }
315                 }
316                 jsonString.Append("},");
317             }
318             jsonString.Remove(jsonString.Length - 1, 1);
319             jsonString.Append("]");
320             if (jsonString.Length == 1)
321             {
322                 return "[]";
323             }
324             return jsonString.ToString();
325         }
326         #endregion
327
328         #region  DataTable转成Json
329         /// <summary>
330         /// DataTable转成Json
331         /// </summary>
332         /// <param name="jsonName"></param>
333         /// <param name="dt"></param>
334         /// <returns></returns>
335         public static string ToJson(DataTable dt, string jsonName)
336         {
337             StringBuilder Json = new StringBuilder();
338             if (string.IsNullOrEmpty(jsonName))
339                 jsonName = dt.TableName;
340             Json.Append("{\"" + jsonName + "\":[");
341             if (dt.Rows.Count > 0)
342             {
343                 for (int i = 0; i < dt.Rows.Count; i++)
344                 {
345                     Json.Append("{");
346                     for (int j = 0; j < dt.Columns.Count; j++)
347                     {
348                         Type type = dt.Rows[i][j].GetType();
349                         Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j] is DBNull ? string.Empty : dt.Rows[i][j].ToString(), type));
350                         if (j < dt.Columns.Count - 1)
351                         {
352                             Json.Append(",");
353                         }
354                     }
355                     Json.Append("}");
356                     if (i < dt.Rows.Count - 1)
357                     {
358                         Json.Append(",");
359                     }
360                 }
361             }
362             Json.Append("]}");
363             return Json.ToString();
364         }
365         #endregion
366
367         #region DataReader转换为Json
368         /// <summary>
369          /// DataReader转换为Json
370          /// </summary>
371           /// <param name="dataReader">DataReader对象</param>
372           /// <returns>Json字符串</returns>
373         public static string ToJson(IDataReader dataReader)
374         {
375             try
376             {
377                 StringBuilder jsonString = new StringBuilder();
378                 jsonString.Append("[");
379
380                 while (dataReader.Read())
381                 {
382                     jsonString.Append("{");
383                     for (int i = 0; i < dataReader.FieldCount; i++)
384                     {
385                         Type type = dataReader.GetFieldType(i);
386                         string strKey = dataReader.GetName(i);
387                         string strValue = dataReader[i].ToString();
388                         jsonString.Append("\"" + strKey + "\":");
389                         strValue = StringFormat(strValue, type);
390                         if (i < dataReader.FieldCount - 1)
391                         {
392                             jsonString.Append(strValue + ",");
393                         }
394                         else
395                         {
396                             jsonString.Append(strValue);
397                         }
398                     }
399                     jsonString.Append("},");
400                 }
401                 if (!dataReader.IsClosed)
402                 {
403                     dataReader.Close();
404                 }
405                 jsonString.Remove(jsonString.Length - 1, 1);
406                 jsonString.Append("]");
407                 if (jsonString.Length == 1)
408                 {
409                     return "[]";
410                 }
411                 return jsonString.ToString();
412             }
413             catch (Exception ex)
414             {
415                 throw ex;
416             }
417         }
418         #endregion
419
420         #region DataSet转换为Json
421         /// <summary>
422          /// DataSet转换为Json
423         /// </summary>
424         /// <param name="dataSet">DataSet对象</param>
425          /// <returns>Json字符串</returns>
426         public static string ToJson(DataSet dataSet)
427         {
428             string jsonString = "{";
429             foreach (DataTable table in dataSet.Tables)
430             {
431                 jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ",";
432             }
433             jsonString = jsonString.TrimEnd(‘,‘);
434             return jsonString + "}";
435         }
436         #endregion
437
438         #region 过滤特殊字符
439         /// <summary>
440          /// 过滤特殊字符
441          /// </summary>
442          /// <param name="s"></param>
443          /// <returns></returns>
444         public static string String2Json(String s)
445         {
446             StringBuilder sb = new StringBuilder();
447             for (int i = 0; i < s.Length; i++)
448             {
449                 char c = s.ToCharArray()[i];
450                 switch (c)
451                 {
452                     case ‘\"‘:
453                         sb.Append("\\\""); break;
454                     case ‘\\‘:
455                         sb.Append("\\\\"); break;
456                     case ‘/‘:
457                         sb.Append("\\/"); break;
458                     case ‘\b‘:
459                         sb.Append("\\b"); break;
460                     case ‘\f‘:
461                         sb.Append("\\f"); break;
462                     case ‘\n‘:
463                         sb.Append("\\n"); break;
464                     case ‘\r‘:
465                         sb.Append("\\r"); break;
466                     case ‘\t‘:
467                         sb.Append("\\t"); break;
468                     case ‘\v‘:
469                         sb.Append("\\v"); break;
470                     case ‘\0‘:
471                         sb.Append("\\0"); break;
472                     default:
473                         sb.Append(c); break;
474                 }
475             }
476             return sb.ToString();
477         }
478         #endregion
479
480         #region 格式化字符型、日期型、布尔型
481         /// <summary>
482          /// 格式化字符型、日期型、布尔型
483          /// </summary>
484          /// <param name="str"></param>
485          /// <param name="type"></param>
486         /// <returns></returns>
487         private static string StringFormat(string str, Type type)
488         {
489             if (type != typeof(string) && string.IsNullOrEmpty(str))
490             {
491                 str = "\"" + str + "\"";
492             }
493             else if (type == typeof(string))
494             {
495                 str = String2Json(str);
496                 str = "\"" + str + "\"";
497             }
498             else if (type == typeof(DateTime))
499             {
500                 str = "\"" + str + "\"";
501             }
502             else if (type == typeof(bool))
503             {
504                 str = str.ToLower();
505             }
506             else if (type == typeof(byte[]))
507             {
508                 str = "\"" + str + "\"";
509             }
510             else if (type == typeof(Guid))
511             {
512                 str = "\"" + str + "\"";
513             }
514             return str;
515         }
516
517         #endregion
518     }
519 }

时间: 2024-10-13 11:47:01

[.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) JSON序列化利器 Newtonsoft.Json 及 通用Json类的相关文章

[.net 面向对象程序设计进阶] (1) 开篇

[.net 面向对象程序设计进阶] (1) 开篇 上一系列文章<.net 面向对象编程基础>写完后,很多小伙伴们希望我有时间再写一点进阶的文章,于是有了这个系列文章.这一系列的文章中, 对于.net 基础的一些知识,推荐小伙伴们阅读一下我上一系列文章<.net 面向对象编程基础> ,也就是说本篇文章在阅读前,最好是掌握了.net 的基础知识. 首先,“.net 面向对象程序设计进阶”这一系列的文章涉及的范围比较广,每一节相当于.net的一个分支,基本可以作为一个独立的课题了.只所以

[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口IXmlSerializable实现XML序列化及XML通用类

[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口IXmlSerializable实现XML序列化及XML通用类 本节导读:本节主要介绍通过序列化接口IXmlSerializable实现XML序列化和反序列化,整理了XML基础操作及序列化的通用类(包括XML及节点的基础读写操作,XML到DataSet\DataTable互转换操作,XML序列化及反序列化通用方法等). 读前必备: A.类和类的实例 [.net 面向对象编程基础]  (9) 类和类的

[.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

[.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.NET中快带序列化和反序列化.最后介绍在使用.NET序列化JSON过程中的注意事项. 读前必备: A.泛型       [.net 面向对象编程基础]  (18) 泛型 B.LINQ使用  [.net 面向对象编程基础] (20) LINQ使用 1. 关于JSON JSON的全称是”JavaScrip

[.net&#160;面向对象程序设计进阶] (9) 序列化(Serialization) (一) 二进制流序列化

[.net 面向对象程序设计进阶]  (9)  序列化(Serialization) (一) 二进制流序列化 本节导读: 在.NET编程中,经常面向对象处理完以后要转换成另一种格式传输或存储,这种将对象转向其他数据格式的过程,即序列化(Serialization). 与之相反的过程就是反序列化(Deserialization).掌握和利用好序列化和反序列化的方法,对提高面向编程技术很有益处. 读前必备: A.类和类的实例  [.net 面向对象编程基础]  (9) 类和类的实例  B.类的成员

[.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit

[.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit 读前必备: 接上篇: 分布式版本控制系统Git——使用GitStack+TortoiseGit 图形界面搭建Git环境 http://www.cnblogs.com/yubinfeng/p/5182271.html 本篇导读: 上篇介绍了一款Windows环境下的Git服务器工具GitStack ,搭建了最简单的Windows下的Git服务器,需要再次提醒的是

[.net 面向对象程序设计进阶] (2) 正则表达式 (二)

[.net 面向对象程序设计进阶] (2) 正则表达式 (二) 上一节我们说到了C#使用正则表达式的几种方法(Replace,Match,Matches,IsMatch,Split等),还有正则表达式的几种元字符及其应用实例,这些都是学习正则表达式的基础.本节,我们继续深入学习表达式的几种复杂的用法. 1.分组 用小括号来指定子表达式(也叫做分组) 我们通过前一节的学习,知道了重复单个字符,只需要在字符后面加上限定符就可以了, 比如 a{5},如果要重复多个字符,就要使用小括号分组,然后在后面加

[.net 面向对象程序设计进阶] (2) 正则表达式(一)

[.net 面向对象程序设计进阶] (2) 正则表达式(一) 1.什么是正则表达式? 1.1正则表达式概念 正则表达式,又称正则表示法,英文名:Regular Expression(简写为regex.regexp或RE),是计算机科学的一个重要概念.他是用一种数学算法来解决计算机程序中的文本检索.区配等问题. 1.2正则表达式语言支持  正则表达式其实与语言无关,在很多语言中都提供了支持 ,包括最常用的脚本语言Javascript.当然C#语言也毫不例外的提供了很好的支持.     正则表达式语

[.net 面向对象程序设计进阶] (4) 正则表达式 (三) 表达式助手

[.net 面向对象程序设计进阶] (2) 正则表达式(三) 表达式助手 上面两节对正则表达式的使用及.NET下使用正则表达式作了详细说明,本节主要搜集整理了常用的正则表达式提供参考. 此外为了使用方便,编写了一个<正则表达式助手>方便测试正则表达式. 1.正则表达式助手 1.1 软件概述 软件名称: <正则表达式助手> 版本: 1.0 最后更新日期: 2015/07/01 作者: YuBinfeng 运行环境: .NET Framework 4.6及以上(常用表达式功能,需要联网

[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是时候来引用他解决问题.而本节主要目的就是使用表达式树解决实际问题. 读前必备: 本节学习前,需要掌握以下知识: A.继承 [.net 面向对象编程基础]  (12) 面向对象三大特性——继承 B.多态 [.net 面向对象编程基础]  (13) 面向对象三大特性——多态 C.抽象类 [.net 面向