C#中实现JSON功能及对象的序列化和反序列化

Newtonsoft.Json程序包的引用

c#中使用json功能,需要Newtonsoft.Json程序包,可以通过NuGet程序包管理器搜索Newtonsoft.Json来安装,也可以在NuGet程序包管理器控制台下使用以下命令来安装:

install-package Newtonsoft.Json

然后引用NewTonSoft.Json命名空间。之后就可以将建立的对象转换为JSON字符串了。

将对象序列化为JSON字符串

如下创建一个类

public class Student

{

    public int Id { get; set; }

    public string Name { get; set; }

    public string Sex { get; set; }

    public string Description { get; set; }

}

生成对象并序列化为JSON字符串

List<Student> students = new List<Student>();

students.Add(new Student { Id = 1, Name = "张三", Sex = "男", Description = "班长" });

students.Add(new Student { Id = 2, Name = "李四", Sex = "女", Description = "小组长" });

students.Add(new Student { Id = 3, Name = "王五", Sex = "男", Description = "宣传委员" });

string studentsJson = JsonConvert.SerializeObject(students);

Console.WriteLine(studentsJson);

输出结果:

[{“Id”:1,”Name”:”张三”,”Sex”:”男”,”Description”:”班长”},{“Id”:2,”Name”:”李四”,”Sex”:”女”,”Description”:”小组长”},{“Id”:3,”Name”:”王五”,”Sex”:”男”,”Description”:”宣传委员”}]

使用[JsonIgnore]特性忽略字段的序列化

有时我们可能不希望某些字段参与对象的JSON序列化,此时可以在该字段上使用[JsonIgnore]特性,对象被序列化后不会包含被忽略的字段

public class Student

{

    public int Id { get; set; }

    public string Name { get; set; }

    [JsonIgnore]

    public string Sex { get; set; }

    public string Description { get; set; }

}

输出结果:

[{“Id”:1,”Name”:”张三”,”Description”:”班长”},{“Id”:2,”Name”:”李四”,”Description”:”小组长”},{“Id”:3,”Name”:”王五”,”Description”:”宣传委员”}]

使用[JsonProperty]特性标识字段的序列化名称

有时我们可能想在对象序列化时更换字段的输出名称,譬如简化字段名称以缩短JSON字符串的长度,此时可使用[JsonProperty]特性标识字段

public class Student

{

    public int Id { get; set; }

    public string Name { get; set; }

    [JsonIgnore]

    public string Sex { get; set; }

    [JsonProperty("Desc")]

    public string Description { get; set; }

}

输出结果:

[{“Id”:1,”Name”:”张三”,”Desc”:”班长”},{“Id”:2,”Name”:”李四”,”Desc”:”小组长”},{“Id”:3,”Name”:”王五”,”Desc”:”宣传委员”}]

格式化输出JSON字符串

如果要将生成的JSON字符串以友好的格式化形式输出,可调用以下方法来转换

/// <summary>

/// 格式化JSON字符串

/// </summary>

/// <param name="str"></param>

/// <returns></returns>

private static string ConvertJsonString(string str)

{

    JsonSerializer serializer = new JsonSerializer();

    TextReader tr = new StringReader(str);

    JsonTextReader jtr = new JsonTextReader(tr);

    object obj = serializer.Deserialize(jtr);

    if (obj != null)

    {

        StringWriter textWriter = new StringWriter();

        JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)

        {

            Formatting = Formatting.Indented,

            Indentation = 4,

            IndentChar = ' '

        };

        serializer.Serialize(jsonWriter, obj);

        return textWriter.ToString();

    }

    else

    {

        return str;

    }

}

于是上面的JSON字符串可改用格式化的形式输出

List<Student> students = new List<Student>();

students.Add(new Student { Id = 1, Name = "张三", Sex = "男", Description = "班长" });

students.Add(new Student { Id = 2, Name = "李四", Sex = "女", Description = "小组长" });

students.Add(new Student { Id = 3, Name = "王五", Sex = "男", Description = "宣传委员" });

//string studentsJson = JsonConvert.SerializeObject(students);

string studentsJson = ConvertJsonString(JsonConvert.SerializeObject(students));

Console.WriteLine(studentsJson);

输出结果:

[

{

“Id”: 1,

“Name”: “张三”,

“Desc”: “班长”

},

{

“Id”: 2,

“Name”: “李四”,

“Desc”: “小组长”

},

{

“Id”: 3,

“Name”: “王五”,

“Desc”: “宣传委员”

}

]

JSON字符串的反序列化

以下例子将构建的JSON字符串反序列化为对象,类的定义不要使用以上描述的两个附加特性

public class Student

{

    public int Id { get; set; }

    public string Name { get; set; }

    //[JsonIgnore]

    public string Sex { get; set; }

    //[JsonProperty("Desc")]

    public string Description { get; set; }

}

string inputJsonString = @"[

{ Id: 1, Name: '张三', Sex: '男', Description: '班长' },

{ Id: 2, Name: '李四', Sex: '女', Description: '小组长' },

{ Id: 3, Name: '王五', Sex: '男', Description: '宣传委员' }

]";

List<Student> objects = JsonConvert.DeserializeObject<List<Student>>(inputJsonString);

foreach (Student item in objects)

{

Console.WriteLine($"Id: {item.Id}, Name: {item.Name}, Sex: {item.Sex}, Description: {item.Description}");

}

输出结果:

Id: 1, Name: 张三, Sex: 男, Description: 班长

Id: 2, Name: 李四, Sex: 女, Description: 小组长

Id: 3, Name: 王五, Sex: 男, Description: 宣传委员

一般对象的序列化和反序列化

有时候我们可能需要序列化一个对象到字符串,或者反序列化字符串到对象,如对一个类进行封装传输或者存储。这首先需要使用特性[Serializable]将该对象类型标记为可序列化

// 标记类型可序列化

[Serializable]

public class Student

{

    public int Id { get; set; }

    public string Name { get; set; }

    public string Sex { get; set; }

    public string Description { get; set; }

}

一般对象的序列化和反序列化可以用以下两个方法来实现

/// <summary>

/// 序列化对象到字符串

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="obj"></param>

/// <returns></returns>

private static string Serialize<T>(T obj)

{

    try

    {

        IFormatter formatter = new BinaryFormatter();

        MemoryStream stream = new MemoryStream();

        formatter.Serialize(stream, obj);

        stream.Position = 0;

        byte[] buffer = new byte[stream.Length];

        stream.Read(buffer, 0, buffer.Length);

        stream.Flush();

        stream.Close();

        return Convert.ToBase64String(buffer);

    }

    catch (Exception ex)

    {

        throw new Exception(ex.Message);

    }

}

/// <summary>

/// 反序列化字符串到对象

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="obj"></param>

/// <param name="str"></param>

/// <returns></returns>

public static T Deserialize<T>(T obj, string str)

{

    try

    {

        obj = default(T);

        IFormatter formatter = new BinaryFormatter();

        byte[] buffer = Convert.FromBase64String(str);

        MemoryStream stream = new MemoryStream(buffer);

        obj = (T)formatter.Deserialize(stream);

        stream.Flush();

        stream.Close();

    }

    catch (Exception ex)

    {

        throw new Exception(ex.Message);

    }

    return obj;

}

以下例子使用上述两个方法实现一般对象的序列化和反序列化

List<Student> students = new List<Student>();

students.Add(new Student { Id = 1, Name = "张三", Sex = "男", Description = "班长" });

students.Add(new Student { Id = 2, Name = "李四", Sex = "女", Description = "小组长" });

students.Add(new Student { Id = 3, Name = "王五", Sex = "男", Description = "宣传委员" });

string studentsString = Serialize(students);

Console.WriteLine($"序列化后的对象:\n{studentsString}");

List<Student> objects = new List<Student>();

objects = Deserialize(objects, studentsString);

Console.WriteLine("反序列化后的对象:");

foreach (Student item in objects)

{

    Console.WriteLine($"Id: {item.Id}, Name: {item.Name}, Sex: {item.Sex}");

}

输出结果:

序列化后的对象:

AAEAAAD/////AQAAAAAAAAAMAgAAAEJDb25zb2xlQXBwMSwgVmVyc2lvbj0xLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPW51bGwEAQAAAHxTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW0NvbnNvbGVBcHAxLlN0dWRlbnQsIENvbnNvbGVBcHAxLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbF1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24EAAAVQ29uc29sZUFwcDEuU3R1ZGVudFtdAgAAAAgICQMAAAADAAAAAwAAAAcDAAAAAAEAAAAEAAAABBNDb25zb2xlQXBwMS5TdHVkZW50AgAAAAkEAAAACQUAAAAJBgAAAAoFBAAAABNDb25zb2xlQXBwMS5TdHVkZW50BAAAABM8SWQ+a19fQmFja2luZ0ZpZWxkFTxOYW1lPmtfX0JhY2tpbmdGaWVsZBQ8U2V4PmtfX0JhY2tpbmdGaWVsZBw8RGVzY3JpcHRpb24+a19fQmFja2luZ0ZpZWxkAAEBAQgCAAAAAQAAAAYHAAAABuW8oOS4iQYIAAAAA+eUtwYJAAAABuePremVvwEFAAAABAAAAAIAAAAGCgAAAAbmnY7lm5sGCwAAAAPlpbMGDAAAAAnlsI/nu4Tplb8BBgAAAAQAAAADAAAABg0AAAAG546L5LqUCQgAAAAGDwAAAAzlrqPkvKDlp5TlkZgL

反序列化后的对象:

Id: 1, Name: 张三, Sex: 男

Id: 2, Name: 李四, Sex: 女

Id: 3, Name: 王五, Sex: 男

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容