JSON

Json.Net学习笔记(十三) 缩小序列化Json的大小

字号+ 作者:H5之家 来源:H5之家 2017-03-01 16:01 我要评论( )

当序列化.Net对象为Json对象时经常会遇到的一个问题是:最终的Json包含大量多余的属性和属性值。这个问题在返回Json到客户端时显得特别重要。Json越大意味着需要

当序列化.Net对象为Json对象时经常会遇到的一个问题是:最终的Json包含大量多余的属性和属性值。这个问题在返回Json到客户端时显得特别重要。Json越大意味着需要更大的带宽,使网速变得更慢。

为了解决多余的Json这个问题,Json.Net有一系列内置的选项可以进行调整。

->JsonIgnoreAttribute and DataMemberAttribute

默认情况下,在Json创建的时候Json.Net会包含所有类级别的public属性和字段。添加JsonIgnoreAttribute到属性上,告诉序列化器序列化时跳过它。

public class Car
{
// included in JSON
public string Model { get; set; }
public DateTime Year { get; set; }
public List<string> Features { get; set; }

// ignored
[JsonIgnore]
public DateTime LastModified { get; set; }
}

如果类有很多属性,你只想序列化它的一小部分,添加JsonIgore到所有其他的属性上会比较冗余,也比较容易出错。有一种用来处理这种情况的方法,添加DataContractAttribute到类上,添加DataMemberAttribute到需要被序列化的属性上。与使用JsonIgnoreAttribute的opt-out序列化相比,opt-in序列化仅仅你标记的属性被需列化。

using System.Runtime.Serialization;

[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }

// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}

->Formatting

Json序列化时,用可选参数Formatting.Indented生成良好的显示格式,可读性更好。另一方面,Formatting.None会跳过不必要的空格和换行符,让Json的结果更小。生成的显示格式更加紧凑,也许效率更高。

->NullValueHandling

在序列化器中NullVlaueHandling是可选的。它控制序列化器如何处理值为null的属性。通过设置NullValueHandling.Ignore值,序列化器会跳过值为null的属性。

public class Movie
{
public string Name { get; set; }
public string Description { get; set; }
public string Classification { get; set; }
public string Studio { get; set; }
public DateTime? ReleaseDate { get; set; }
public List<string> ReleaseCountries { get; set; }
}

测试1:

Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";

string included = JsonConvert.SerializeObject(movie,
Formatting.Indented,
new JsonSerializerSettings { });
Console.WriteLine(included);

输出结果:

{
"Name": "Bad Boys III",
"Description": "It's no Bad Boys",
"Classification": null,
"Studio": null,
"ReleaseDate": null,
"ReleaseCountries": null
}

测试2:

string ignored = JsonConvert.SerializeObject(movie,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Console.WriteLine(ignored);

输出结果:

{
"Name": "Bad Boys III",
"Description": "It's no Bad Boys"
}

NullValueHandling也可以在单独的属性上用JsonPropertyAttribute进行定制。使用JsonPropertyAttribute时设置的NullValueHandling值会在Json序列化器中为该属性进行重写。

->DefaultValuehandling

在序列化器中DefaultValuehandling是可选的。它控制序列化器如何处理带有默认值的属性。通过设置DefaultValuehandling.Ignore值,序列化器会跳过带有默认值的属性。对于引用类型为null,对于值类型,如int和DateTime,序列化器将跳过默认未初使化值的值类型。

Json.Net也允许你通过DefaultValueAttribute自定义默认值,例如:如果一个字符串类型的属性Department在它的默认状态下总是返回一个空字符,但是在你的Json对象中你不想要那个空字符串,你可以在Department上使用空字符串参数标记DefaultValueAttribute,这意味着Department在序列化时不再写入Json中,除非它有非空值。

public class Invoice
{
public string Company { get; set; }
public decimal Amount { get; set; }

// false is default value of bool
public bool Paid { get; set; }
// null is default value of nullable
public DateTime? PaidDate { get; set; }

// customize default values
[DefaultValue(30)]
public int FollowUpDays { get; set; }
[DefaultValue("")]
public string FollowUpEmailAddress { get; set; }
}

测试1:

Invoice invoice = new Invoice
{
Company = "Acme Ltd.",
Amount = 50.0m,
Paid = false,
FollowUpDays = 30,
FollowUpEmailAddress = string.Empty,
PaidDate = null
};

string includedDefaultValue = JsonConvert.SerializeObject(invoice,
Formatting.Indented,
new JsonSerializerSettings { });
Console.WriteLine(includedDefaultValue);

输出结果:

{
"Company": "Acme Ltd.",
"Amount": 50.0,
"Paid": false,
"PaidDate": null,
"FollowUpDays": 30,
"FollowUpEmailAddress": ""
}

测试2:

string ignoredDefaultValue = JsonConvert.SerializeObject(invoice,
Formatting.Indented,
new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
Console.WriteLine(ignoredDefaultValue);

输出结果:

{
"Company": "Acme Ltd.",
"Amount": 50.0,
"Paid": false//??
}

DefaultValueHandling也可以在单独的属性上用JsonPropertyAttribute进行定制。使用JsonPropertyAttribute时设置的DefaultValueHandling值会在Json序列化器中为该属性进行重写。

->IContractResolver

为了获得更多的灵活性,IContractResolver接口提供了定制.Net对象序列化为Json的每一个方面,包括在运行时改变序列化的行为。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Json.Net学习笔记(四) Json对象的读写

    Json.Net学习笔记(四) Json对象的读写

    2017-02-27 08:02

  • [C++]Json 学习笔记

    [C++]Json 学习笔记

    2017-02-26 18:01

  • Azure机器学习入门(4)模型发布为Web服务

    Azure机器学习入门(4)模型发布为Web服务

    2017-02-24 09:52

  • Node.js学习之模块化机制原理详解

    Node.js学习之模块化机制原理详解

    2017-02-18 16:03

网友点评
/