[.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官方的性能测试图表。

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

功能方面,当然不用说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[]{"周伯通", ,"重阳宫" });
dt1.Rows.Add(new object[]{"洪七公", ,"丐帮" });
dt1.Rows.Add(new object[]{"黄药师",,"桃花岛" });
dt1.Rows.Add(new object[]{"欧阳锋",,"白驼山" }); //创建 DataTable 2
DataTable dt2 = dt1.Clone();
dt2.TableName = "Second";
dt2.Rows.Add(new object[]{"郭靖",,"丐帮"});
dt2.Rows.Add(new object[]{"黄蓉",,"丐帮"});
dt2.Rows.Add(new object[]{ "梅超风", ,"桃花岛"});
dt2.Rows.Add(new object[]{ "杨康", ,"金"}); //创建DataSet
DataSet ds = new DataSet("Master");
ds.Tables.AddRange(new DataTable[]{ dt1,dt2}); //序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(ds);
Console.WriteLine(myJsonStr);

运行结果如下 :

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

下面将上面生成的字符串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");
}
}

运行结果如下:

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

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=, name="段誉", menpai="天龙寺", kongFu="六脉神剑"},
new MartialArtsMaster(){ id=, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
new MartialArtsMaster(){ id=, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList);
Console.WriteLine(myJsonStr);

运行结果如下:

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

下面看一下包含模式(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=, name="段誉", menpai="天龙寺", kongFu="六脉神剑"},
new MartialArtsMaster(){ id=, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
new MartialArtsMaster(){ id=, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList);
Console.WriteLine(myJsonStr);

运行结果如果如下:

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

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=, name="段誉", menpai="天龙寺"},
new MartialArtsMaster(){ id=, name="乔峰", menpai="丐帮", kongFu="降龙十八掌"},
new MartialArtsMaster(){ id=, name="虚竹", menpai="逍遥派", kongFu="北冥神功"}
};
//设置默认处理项
JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
jsonSettings.NullValueHandling = NullValueHandling.Ignore; //序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList,Formatting.Indented,jsonSettings);
Console.WriteLine(myJsonStr);

运行结果如下:

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

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=, name="段誉", Birthday=new DateTime(,,,,,)},
new MartialArtsMaster(){ id=, name="乔峰", Birthday=new DateTime(,,)},
new MartialArtsMaster(){ id=, name="虚竹", Birthday=new DateTime(,,), DebutTime=new DateTime(,,)}
}; //序列化DataSet为Json字符串
string myJsonStr = JsonConvert.SerializeObject(masterList,Formatting.Indented);
Console.WriteLine(myJsonStr);

运行结果如下:

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

F.自定义成员名 

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

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

[JsonProperty(PropertyName = "名字")]

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

G.动态成员清单 

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

下面列举动态构造对象成员,序列化Json

 /// <summary>
/// 动态动态成员
/// </summary>
public class MyPropsContractResolver : DefaultContractResolver
{
string[] props = null;
public MyPropsContractResolver(string[] props)
{
//属性的清单
this.props = props;
}
//重写创建要序列化的属性
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
//只保留清单有列出的属性
return list.Where(p => props.Contains(p.PropertyName)).ToList();
}
}

通过继承DefaultContractResolver类,重写CreateProperties属性清单方法

下面是调用,实体类还是上面的“武林高手”,这里不再列举。

//增加几个武林高手
List<MartialArtsMaster> masterList = new List<MartialArtsMaster>() {
new MartialArtsMaster(){ id=, name="段誉", Birthday=new DateTime(,,,,,)},
new MartialArtsMaster(){ id=, name="乔峰", Birthday=new DateTime(,,)},
new MartialArtsMaster(){ id=, name="虚竹", Birthday=new DateTime(,,), DebutTime=new DateTime(,,)}
}; JsonSerializerSettings jsetting = new JsonSerializerSettings();
var propertiesList = new string[] { "name", "Birthday", "DebutTime" };
jsetting.ContractResolver = new MyPropsContractResolver(propertiesList);
Console.WriteLine(JsonConvert.SerializeObject(masterList, Formatting.Indented, jsetting));

运行结果如下:

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

真正的做到了,想让他列举那些列就列举那些,最主要的一点,可以不用在实体中标记了,这个非常方便。

Newtonsoft.Json的功能远不止这些

比如 Newtonsoft.Json.Linq 提供了使用Linq查询JSON的很多方法,希望小伙伴闲暇慢慢控究。

更加详细的使用,可以参考官方网站的示例有100多个,还有详细的API文档

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

2.  JSON通用类

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

命名空间:KaJiMao.Common

类名:JsonHelper

文件名:JsonHelper.cs

 using System;
using System.Data;
using System.Text;
using System.Collections.Generic;
using System.Reflection;
using System.Data.Common;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Json; namespace KaJiMao.Common
{
/// <summary>
/// Json通用类
/// Yubinfeng
/// Date:2015/07/11 public static class JsonHepler
{
#region List序列化为 Json 字符串
/// <summary>
  /// List序列化为 Json 字符串
/// </summary>
  /// <typeparam name="T"></typeparam>
/// <param name="jsonName"></param>
 /// <param name="list"></param>
/// <returns></returns>
public static string ListToJson<T>(IList<T> list, string jsonName)
{
StringBuilder Json = new StringBuilder();
if (string.IsNullOrEmpty(jsonName))
jsonName = list[].GetType().Name;
Json.Append("{\"" + jsonName + "\":[");
if (list.Count > )
{
for (int i = ; i < list.Count; i++)
{
T obj = Activator.CreateInstance<T>();
PropertyInfo[] pi = obj.GetType().GetProperties();
Json.Append("{");
for (int j = ; j < pi.Length; j++)
{
Type type;
object o = pi[j].GetValue(list[i], null);
string v = string.Empty;
if (o != null)
{
type = o.GetType();
v = o.ToString();
}
else
{
type = typeof(string);
} Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(v, type)); if (j < pi.Length - )
{
Json.Append(",");
}
}
Json.Append("}");
if (i < list.Count - )
{
Json.Append(",");
}
}
}
Json.Append("]}");
return Json.ToString();
}
#endregion #region 序列化集合对象
/// <summary>
/// 序列化集合对象
  /// </summary>
public static string JsonSerializerByArrayData<T>(T[] tArray)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T[]));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, tArray);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
string p = @"\\/Date\((\d+)\+\d+\)\\/";
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
Regex reg = new Regex(p);
jsonString = reg.Replace(jsonString, matchEvaluator);
return jsonString;
}
#endregion #region 序列化单个对象
/// <summary>
/// 序列化单个对象
/// </summary>
public static string JsonSerializerBySingleData<T>(T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
string p = @"\\/Date\((\d+)\+\d+\)\\/";
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
Regex reg = new Regex(p);
jsonString = reg.Replace(jsonString, matchEvaluator);
return jsonString;
}
#endregion #region 反序列化单个对象
/// <summary>
/// 反序列化单个对象
 /// </summary>
public static T JsonDeserializeBySingleData<T>(string jsonString)
{
            //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式 
            string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
Regex reg = new Regex(p);
jsonString = reg.Replace(jsonString, matchEvaluator);
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
#endregion #region 反序列化集合对象
/// <summary>
 /// 反序列化集合对象
/// </summary>
public static T[] JsonDeserializeByArrayData<T>(string jsonString)
{
            //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式 
            string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
Regex reg = new Regex(p);
jsonString = reg.Replace(jsonString, matchEvaluator);
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T[]));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T[] arrayObj = (T[])ser.ReadObject(ms);
return arrayObj;
}
#endregion #region 将Json序列化时间转为字符串 ("yyyy-MM-dd HH:mm:ss")
/// <summary>
 /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串
 /// </summary>
private static string ConvertJsonDateToDateString(Match m)
{
string result = string.Empty;
DateTime dt = new DateTime(, , );
dt = dt.AddMilliseconds(long.Parse(m.Groups[].Value));
dt = dt.ToLocalTime();
result = dt.ToString("yyyy-MM-dd HH:mm:ss");
return result;
}
#endregion #region 将时间字符串转为Json时间
/// <summary> 
 /// 将时间字符串转为Json时间
/// </summary>
private static string ConvertDateStringToJsonDate(Match m)
{
string result = string.Empty;
DateTime dt = DateTime.Parse(m.Groups[].Value);
dt = dt.ToUniversalTime();
TimeSpan ts = dt - DateTime.Parse("1970-01-01");
result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
return result;
}
#endregion #region ist转成json
/// <summary>
 /// List转成json
 /// </summary>
 /// <typeparam name="T"></typeparam>
  /// <param name="list"></param>
 /// <returns></returns>
public static string ListToJson<T>(IList<T> list)
{
object obj = list[];
return ListToJson<T>(list, obj.GetType().Name);
}
#endregion #region 对象转换为Json字符串
/// <summary>
/// 对象转换为Json字符串
/// </summary>
/// <param name="jsonObject">对象</param>
  /// <returns>Json字符串</returns>
public static string ToJson(object jsonObject)
{
try
{
StringBuilder jsonString = new StringBuilder();
jsonString.Append("{");
PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties();
for (int i = ; i < propertyInfo.Length; i++)
{
object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null);
if (objectValue == null)
{
continue;
}
StringBuilder value = new StringBuilder();
if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan)
{
value.Append("\"" + objectValue.ToString() + "\"");
}
else if (objectValue is string)
{
value.Append("\"" + objectValue.ToString() + "\"");
}
else if (objectValue is IEnumerable)
{
value.Append(ToJson((IEnumerable)objectValue));
}
else
{
value.Append("\"" + objectValue.ToString() + "\"");
}
jsonString.Append("\"" + propertyInfo[i].Name + "\":" + value + ","); ;
}
return jsonString.ToString().TrimEnd(',') + "}";
}
catch (Exception ex)
{
throw ex;
}
}
#endregion #region 对象集合转换Json
/// <summary>
 /// 对象集合转换Json
 /// </summary>
 /// <param name="array">集合对象</param>
 /// <returns>Json字符串</returns>
public static string ToJson(IEnumerable array)
{
string jsonString = "[";
foreach (object item in array)
{
jsonString += ToJson(item) + ",";
}
if (jsonString.Length > )
{
jsonString.Remove(jsonString.Length - , jsonString.Length);
}
else
{
jsonString = "[]";
}
return jsonString + "]";
}
#endregion #region 普通集合转换Json
/// <summary>
/// 普通集合转换Json
 /// </summary>
/// <param name="array">集合对象</param>
/// <returns>Json字符串</returns>
public static string ToArrayString(IEnumerable array)
{
string jsonString = "[";
foreach (object item in array)
{
jsonString = ToJson(item.ToString()) + ",";
}
jsonString.Remove(jsonString.Length - , jsonString.Length);
return jsonString + "]";
}
#endregion #region Datatable转换为Json
/// <summary>
 /// Datatable转换为Json
/// </summary>
/// <param name="table">Datatable对象</param>
 /// <returns>Json字符串</returns>
public static string ToJson(DataTable dt)
{
StringBuilder jsonString = new StringBuilder();
jsonString.Append("[");
DataRowCollection drc = dt.Rows;
for (int i = ; i < drc.Count; i++)
{
jsonString.Append("{");
for (int j = ; j < dt.Columns.Count; j++)
{
string strKey = dt.Columns[j].ColumnName;
string strValue = drc[i][j].ToString();
Type type = dt.Columns[j].DataType;
jsonString.Append("\"" + strKey + "\":");
strValue = StringFormat(strValue, type);
if (j < dt.Columns.Count - )
{
jsonString.Append(strValue + ",");
}
else
{
jsonString.Append(strValue);
}
}
jsonString.Append("},");
}
jsonString.Remove(jsonString.Length - , );
jsonString.Append("]");
if (jsonString.Length == )
{
return "[]";
}
return jsonString.ToString();
}
#endregion #region DataTable转成Json
/// <summary>
 /// DataTable转成Json
 /// </summary>
 /// <param name="jsonName"></param>
/// <param name="dt"></param>
/// <returns></returns>
public static string ToJson(DataTable dt, string jsonName)
{
StringBuilder Json = new StringBuilder();
if (string.IsNullOrEmpty(jsonName))
jsonName = dt.TableName;
Json.Append("{\"" + jsonName + "\":[");
if (dt.Rows.Count > )
{
for (int i = ; i < dt.Rows.Count; i++)
{
Json.Append("{");
for (int j = ; j < dt.Columns.Count; j++)
{
Type type = dt.Rows[i][j].GetType();
Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j] is DBNull ? string.Empty : dt.Rows[i][j].ToString(), type));
if (j < dt.Columns.Count - )
{
Json.Append(",");
}
}
Json.Append("}");
if (i < dt.Rows.Count - )
{
Json.Append(",");
}
}
}
Json.Append("]}");
return Json.ToString();
}
#endregion #region DataReader转换为Json
/// <summary>
 /// DataReader转换为Json
 /// </summary>
  /// <param name="dataReader">DataReader对象</param>
  /// <returns>Json字符串</returns>
public static string ToJson(IDataReader dataReader)
{
try
{
StringBuilder jsonString = new StringBuilder();
jsonString.Append("["); while (dataReader.Read())
{
jsonString.Append("{");
for (int i = ; i < dataReader.FieldCount; i++)
{
Type type = dataReader.GetFieldType(i);
string strKey = dataReader.GetName(i);
string strValue = dataReader[i].ToString();
jsonString.Append("\"" + strKey + "\":");
strValue = StringFormat(strValue, type);
if (i < dataReader.FieldCount - )
{
jsonString.Append(strValue + ",");
}
else
{
jsonString.Append(strValue);
}
}
jsonString.Append("},");
}
if (!dataReader.IsClosed)
{
dataReader.Close();
}
jsonString.Remove(jsonString.Length - , );
jsonString.Append("]");
if (jsonString.Length == )
{
return "[]";
}
return jsonString.ToString();
}
catch (Exception ex)
{
throw ex;
}
}
#endregion #region DataSet转换为Json
/// <summary>
 /// DataSet转换为Json
/// </summary>
/// <param name="dataSet">DataSet对象</param>
 /// <returns>Json字符串</returns>
public static string ToJson(DataSet dataSet)
{
string jsonString = "{";
foreach (DataTable table in dataSet.Tables)
{
jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ",";
}
jsonString = jsonString.TrimEnd(',');
return jsonString + "}";
}
#endregion #region 过滤特殊字符
/// <summary>
 /// 过滤特殊字符
 /// </summary>
 /// <param name="s"></param>
 /// <returns></returns>
public static string String2Json(String s)
{
StringBuilder sb = new StringBuilder();
for (int i = ; i < s.Length; i++)
{
char c = s.ToCharArray()[i];
switch (c)
{
case '\"':
sb.Append("\\\""); break;
case '\\':
sb.Append("\\\\"); break;
case '/':
sb.Append("\\/"); break;
case '\b':
sb.Append("\\b"); break;
case '\f':
sb.Append("\\f"); break;
case '\n':
sb.Append("\\n"); break;
case '\r':
sb.Append("\\r"); break;
case '\t':
sb.Append("\\t"); break;
case '\v':
sb.Append("\\v"); break;
case '\0':
sb.Append("\\0"); break;
default:
sb.Append(c); break;
}
}
return sb.ToString();
}
#endregion #region 格式化字符型、日期型、布尔型
/// <summary>
 /// 格式化字符型、日期型、布尔型
 /// </summary>
 /// <param name="str"></param>
 /// <param name="type"></param>
/// <returns></returns>
private static string StringFormat(string str, Type type)
{
if (type != typeof(string) && string.IsNullOrEmpty(str))
{
str = "\"" + str + "\"";
}
else if (type == typeof(string))
{
str = String2Json(str);
str = "\"" + str + "\"";
}
else if (type == typeof(DateTime))
{
str = "\"" + str + "\"";
}
else if (type == typeof(bool))
{
str = str.ToLower();
}
else if (type == typeof(byte[]))
{
str = "\"" + str + "\"";
}
else if (type == typeof(Guid))
{
str = "\"" + str + "\"";
}
return str;
} #endregion
}
}

==============================================================================================

返回目录

 <如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>

<对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>

<转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

.NET 技术交流群:467189533    [.net 面向对象程序设计进阶] (13) 序列化(Serialization)(五) Json 序列化利器 Newtonsoft.Json 及 通用Json类

==============================================================================================

上一篇:在字符编码格式选项里UTF-8(无BOM)的意思


下一篇:利用Maven打包时,如何包含更多的资源文件