1 JSON 的用法
C#中常用 json 保存与分享数据。其中的过程主要是:
(1)程序内的 Class 或 List 或 Hashtable ... -> 序列化为 json 文件或 stream;
(2)加密、传送、接收、解密、(保存 或 不保存)等;
(3)json 反序列化为 Class 或 List 或 Hashtable 等等,用于程序的计算;
2 JSON 序列化 与 反序列化
大家一般都使用 Newtonsoft.Json 进行 json 的序列化与反序列化。
使用 nuget 即可方便使用。
序列化就是将类(内存中定义的一种数据类型):
class mate
{public int Id { get; set; } = -1;public string Name { get; set; } = "";public mate(int id, string name) { Id = id; Name = name; }
}
比如:其中的实例(内存中的数据):
mate one = new mate(110101, "haha");
序列化 后 变成 :
{ "Id" : 110101, "Name" : "haha" }
这样的明文。当然,如果数据多的化,非常不清晰,因而需要一个 格式化 的过程。
变成:
{"Id" : 110101,"Name" : "haha"
}
总结一下:json序列化就是将内存中的(一类)数据转换为标准化的、格式化的明文。反序列化就是将明文转为内存中的(一类)数据。
Newtonsoft.Json 的序列化如下:
mate one = new mate(110101, "haha");
string single = Newtonsoft.Json.JsonConvert.SerializeObject(one);List<mate> two = new List<mate>();
two.Add(new mate(110101, "baba"));
two.Add(new mate(110102, "mama"));
string family = Newtonsoft.Json.JsonConvert.SerializeObject(two);
Newtonsoft.Json 的反序列化则是:
mate oneFF = Newtonsoft.Json.JsonConvert.DeserializeObject<mate>(single);
List<mate> twoFF = Newtonsoft.Json.JsonConvert.DeserializeObject<List<mate>>(family);
3 Newtonsoft.Json 的小问题
Newtonsoft 的 json 组件在效率、可靠性等方面都无与伦比。
但也稍微有点问题:
(1)发布软件必须多带一个 Newtonsoft.Json.dll;不符合纯绿色软件的要求;
(2)不能自动格式化;或者需要另外加一个格式化代码;
4 无需 DLL 的轻量化json序列化与反序列化
一般的小工具,俺都喜欢写成纯绿色代码。
所以一直在使用自己的 json 序列化与反序列化组件,先开放出来共享。
没有DLL;自动格式化;可靠性与效率都OK。
4.1 轻量化json序列化与反序列化的源代码
using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;/// <summary>
/// System.Runtime.Serialization.Json扩展方法类
/// ([DataContract]和[DataMember]联合使用来标记被序列化的字段)
/// </summary>
public static class SimpleJson
{/// <summary>/// 数据格式化的字典/// </summary>private static Dictionary<Type, DataContractJsonSerializer> dic { get; set; } = new Dictionary<Type, DataContractJsonSerializer>();/// <summary>/// TAB对应的空格数/// </summary>private static string TabString { get; set; } = " ";/// <summary>/// 检索合适的数据格式化的字典/// </summary>/// <param name="type"></param>/// <returns></returns>private static DataContractJsonSerializer GetSerializer(Type type){if (!dic.ContainsKey(type)){dic.Add(type, new DataContractJsonSerializer(type));}return dic[type];}/// <summary>/// 将Json字符串反序列化为对象实例/// System.Runtime.Serialization.Json/// ([DataContract]和[DataMember]联合使用来标记被序列化的字段)/// </summary>/// <typeparam name="T">对象类型</typeparam>/// <param name="jsonString">Json字符串</param>/// <returns>对象实例</returns>public static T DeserializeObject<T>(string jsonString){DataContractJsonSerializer ser = GetSerializer(typeof(T));using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))){T jsonObject = (T)ser.ReadObject(ms);return jsonObject;}}/// <summary>/// 将对象实例序列化为Json字符串/// System.Runtime.Serialization.Json/// ([DataContract]和[DataMember]联合使用来标记被序列化的字段)/// </summary>/// <typeparam name="T">对象类型</typeparam>/// <param name="obj">对象实例</param>/// <returns>Json字符串</returns>public static string SerializeObject<T>(T obj){DataContractJsonSerializer ser = GetSerializer(typeof(T));using (MemoryStream ms = new MemoryStream()){ser.WriteObject(ms, obj);ms.Position = 0;using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)){return JsonFormat(sr.ReadToEnd());}}}/// <summary>/// JSON字符串格式化/// </summary>/// <param name="json"></param>/// <returns></returns>public static string JsonFormat(string json){int level = 0;int bracket = 0;StringBuilder sb = new StringBuilder();for (int i = 0; i < json.Length; i++){string c = json.Substring(i, 1);if (level > 0){string tail = sb.ToString();tail = tail.Substring(tail.Length - 1);if (tail == "\n"){sb.Append(LevelSpace(level));}}if (c == "\""){if ((bracket % 2) == 0){sb.Append(c);bracket++;continue;}else{if (json.Substring(i - 1, 1) == "\\"){sb.Append(c);continue;}else{sb.Append(c);bracket--;continue;}}}if ((bracket % 2) == 1){sb.Append(c);continue;}switch (c){case "{":case "[":sb.AppendLine(c);level++;break;case ":":sb.Append(c + " ");break;case ",":sb.AppendLine(c);break;case "}":case "]":sb.AppendLine("");level--;sb.Append(LevelSpace(level) + c);break;default:sb.Append(c);break;}}return sb.ToString();}/// <summary>/// 按数据层次计算前端空格数(4=TAB)/// </summary>/// <param name="level"></param>/// <returns></returns>private static string LevelSpace(int level){
#if __ORIGINAL__string leaf = string.Empty;for (int t = 0; t < level; t++){leaf += TabString;}return leaf;
#endifstring[] sa = new string[level];for (int i = 0; i < sa.Length; i++) sa[i] = TabString;return String.Join("", sa);}
}
4.2 使用轻量化json序列化与反序列化
将上述代码保存为 SimpleJson.cs 文件,将该文件添加之项目。
其他就很简单了。
4.3 轻量化json序列化
// 将 cx 这个类的实例序列化为 json 字符串(自动格式化哦!)
string json = SimpleJson.SerializeObject(cx);
// 保存到文本文件;
File.WriteAllText(filename, json, Encoding.UTF8);
4.4 轻量化json反序列化的代码
// 文本文件读取配置信息 json
string json = File.ReadAllText(filename, Encoding.UTF8);
// 将json反序列化为 ConfigInfo 类的实例 cy
ConfigInfo cy = SimpleJson.DeserializeObject<ConfigInfo>(json);
4.5 可能遇到的问题
可能在这句上出现错误:
using System.Runtime.Serialization.Json;
解决之道:
需要添加 System.Runtime.Serialization 组件。
这个不会需要附加 DLL 文件哦。
没有违反纯绿色软件之约。