[.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
我提供一个下载:https://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.动态成员清单
对于不同的序列化,我们需要的属性或字段如果不同,还可以通过清单来动态完成。
下面列举动态构造对象成员,序列化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=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)} }; JsonSerializerSettings jsetting = new JsonSerializerSettings(); var propertiesList = new string[] { "name", "Birthday", "DebutTime" }; jsetting.ContractResolver = new MyPropsContractResolver(propertiesList); Console.WriteLine(JsonConvert.SerializeObject(masterList, Formatting.Indented, jsetting));
运行结果如下:
真正的做到了,想让他列举那些列就列举那些,最主要的一点,可以不用在实体中标记了,这个非常方便。
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
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 }
==============================================================================================
<如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>
<对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>
<转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>
==============================================================================================
版权声明:本博文原创发表于博客园,作者博客:YuBinfeng's Technology Blog
| |