json.net使用说明二

Posted lgdd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了json.net使用说明二相关的知识,希望对你有一定的参考价值。

1、使用JSON.NET序列化对象
public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}
Account account = new Account
{
    Email = "[email protected]",
    Active = true,
    CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
    Roles = new List<string> { "User", "Admin" }
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
{
  "Email": "[email protected]",
  "Active": true,
  "CreatedDate": "2013-01-20T00:00:00Z",
  "Roles": [
    "User",
    "Admin"
  ]
}
2、使用JSON.NET序列化List集合
List<string> videogames = new List<string> { "零度", "分享", "编程之美" };
string json = JsonConvert.SerializeObject(videogames);
Console.WriteLine(json);
["零度","分享","编程之美"]
3、使用JSON.NET序列化dictionary字典
var points = new Dictionary<string, int> { { "James", 9001 }, { "Jo", 3474 }, { "Jess", 11926 } };
string json = JsonConvert.SerializeObject(points, Formatting.Indented);
Console.WriteLine(json);
{
  "James": 9001,
  "Jo": 3474,
  "Jess": 11926
}
4、将序列化结果保存到指定的文件
public class Movie
{
    public string Name { get; set; }
    public int Year { get; set; }
}
Movie movie = new Movie { Name = "Bad Boys", Year = 1995 };
using (StreamWriter file = File.CreateText(@"e:movie.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(file, movie);
}
5、基于枚举类型的JsonConverters转换器
public enum StringComparison { CurrentCulture = 0, CurrentCultureIgnoreCase = 1, InvariantCulture = 2 }
List<StringComparison> stringComparisons = new List<StringComparison> { 
    StringComparison.CurrentCulture,
    StringComparison.InvariantCulture 
};
string jsonWithoutConverter = JsonConvert.SerializeObject(stringComparisons);
Console.WriteLine(jsonWithoutConverter);
[0,2]
string jsonWithConverter = JsonConvert.SerializeObject(stringComparisons, new StringEnumConverter());
Console.WriteLine(jsonWithConverter);
["CurrentCulture","InvariantCulture"]
var result = JsonConvert.DeserializeObject<List<StringComparison>>(jsonWithConverter, new StringEnumConverter());
Console.WriteLine(string.Join(", ", result.Select(c => c.ToString())));
CurrentCulture, InvariantCulture
6、通过JRaw将JS函数序列化到JSON中
public class javascriptSettings
{
    public JRaw OnLoadFunction { get; set; }
    public JRaw OnUnloadFunction { get; set; }
}
JavaScriptSettings settings = new JavaScriptSettings
{
    OnLoadFunction = new JRaw("OnLoad"),
    OnUnloadFunction = new JRaw("function(e) { alert(e); }")
};
string json = JsonConvert.SerializeObject(settings, Formatting.Indented);
Console.WriteLine(json);
{
  "OnLoadFunction": OnLoad,
  "OnUnloadFunction": function(e) { alert(e); }
}
7、使用JSON.NET反序列化对象
public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}
string json = @"{
   ‘Email‘: ‘[email protected]‘,
   ‘Active‘: true,
   ‘CreatedDate‘: ‘2013-01-20T00:00:00Z‘,
   ‘Roles‘: [
     ‘User‘,
     ‘Admin‘
   ]
 }";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);
[email protected]
8、使用JSON.NET反序列化List集合
string json = @"[‘Starcraft‘,‘Halo‘,‘Legend of Zelda‘]";
List<string> videogames = JsonConvert.DeserializeObject<List<string>>(json);
Console.WriteLine(string.Join(", ", videogames));
Starcraft, Halo, Legend of Zelda
9、使用JSON.NET反序列化dictionary字典
string json = @"{‘href‘: ‘www.xcode.me‘,‘target‘: ‘_blank‘}";
var htmlAttributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(htmlAttributes["href"]);
www.xcode.me
10、序列化var匿名类型
有时候,我们并不需要先定义一个类,然后new一个对象后再进行序列化,JSON.NET支持匿名类型的序列化和反序列化。

var definition = new { Name = "零度编程", Site = "www.xcode.me" };
var json = JsonConvert.SerializeObject(definition);
Console.WriteLine(json);
{ "Name": "零度编程", "Site": "www.xcode.me" }
var definition = new { Name = "", Site = "" };
string json = @"{‘Name‘:‘零度编程‘,‘Site‘:‘www.xcode.me‘}";
var webSite = JsonConvert.DeserializeAnonymousType(json, definition);
Console.WriteLine(webSite.Name);
零度编程
11、用新JSON字符串填充指定对象的属性值
Account account = new Account
{
    Email = "[email protected]",
    Active = true,
    CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
    Roles = new List<string>{"User","Admin"}
};
string json = @"{‘Active‘: false, ‘Roles‘: [‘Expired‘]}";
JsonConvert.PopulateObject(json, account);
Console.WriteLine(account.Active);
false
上面的示例中,account对象的Active值首次设置为true,可通过PopulateObject方法通过json字符串重新填充Active属性和Roles属性。

12、使用JSON.NET反序列化时可指定构造函数
首先我们定义如下的类型,我们希望JSON.NET反序列化对象时使用第2个构造函数,我们将第一个默认构造函数屏蔽,标记为私有private修饰符。第2个构造函数需要指定一个website对象作为参数,如果提供的参数为null则抛出异常:

public class Website
{
    public string Url { get; set; }
    private Website()
    {
    }
    public Website(Website website)
    {
        if (website == null) throw new ArgumentNullException("website");
        Url = website.Url;
    }
}
现在使用一般的方式反序列化一个JSON字符串。

string json = @"{‘Url‘:‘http://www.xcode.me‘}";
try
{
    JsonConvert.DeserializeObject<Website>(json);
}
catch (Exception ex)
{
    Console.WriteLine(ex);
}
Value cannot be null.Parameter name: website
我们发现该序列化方法抛出了异常,并没有按照我们预想的方式进行反序列化,JSON.NET提供如下的方式指定公有构造函数。

Website website = JsonConvert.DeserializeObject<Website>(json, new JsonSerializerSettings
{
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
});
Console.WriteLine(website.Url);
http://www.xcode.me
另外,JSON.NET提供了指定任何构造函数的JsonConstructorAttribute特性,只需要在构造函数上标记,即可指定构造函数。

public class User
{
    public string UserName { get; private set; }
    public bool Enabled { get; private set; }
    public User()
    {
    }
    [JsonConstructor]
    public User(string userName, bool enabled)
    {
        UserName = userName;
        Enabled = enabled;
    }
}
string json = @"{""UserName"": ""www.xcode.me"",""Enabled"": true}";
User user = JsonConvert.DeserializeObject<User>(json);
Console.WriteLine(user.UserName);
www.xcode.me
13、当对象的属性为默认值(0或null)时不序列化该属性

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Partner { get; set; }
    public decimal? Salary { get; set; }
}
Person person = new Person();
string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(jsonIncludeDefaultValues);
{
  "Name": null,
  "Age": 0,
  "Partner": null,
  "Salary": null
}
string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
{
    DefaultValueHandling = DefaultValueHandling.Ignore
});
Console.WriteLine(json);
{}
14、反序列化时JSON属性与对象属性的数量必须一致
默认情况下,JSON.NET反序列化并不要求JSON属性的数量与对象属性的数量相等,也就是始终保持有则序列化,无则不序列化的原则,不会抛出异常。但是,我们的需求并非这样,我们希望属性数量不等或者未提供值时,抛出异常,而不是正常反序列化,可以这样。

public class Account
{
    public string FullName { get; set; }
    public bool Deleted { get; set; }
}
string json = @"{
  ‘FullName‘: ‘Dan Deleted‘,
  ‘Deleted‘: true,
  ‘DeletedDate‘: ‘2013-01-20T00:00:00‘
}";

try
{
    JsonConvert.DeserializeObject<Account>(json, new JsonSerializerSettings
    {
        MissingMemberHandling = MissingMemberHandling.Error
    });
}
catch (JsonSerializationException ex)
{
    Console.WriteLine(ex.Message);
}
Could not find member DeletedDate on object of type Account. Path DeletedDate, line 4, position 23.
这样,当未全部指定对象的属性时,就会抛出异常,而不是部分属性序列化。

15、JSON.NET中忽略null值得处理器
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Partner { get; set; }
    public decimal? Salary { get; set; }
}
Person person = new Person { Name = "Nigal Newborn", Age = 1 };
string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(jsonIncludeNullValues);
{
  "Name": "Nigal Newborn",
  "Age": 1,
  "Partner": null,
  "Salary": null
}
string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
});
Console.WriteLine(json);
{
  "Name": "Nigal Newborn",
  "Age": 1
}
在上面的示例中,默认情况下JSON.NET会将对象的null属性值序列化为JSON中null值。当对象属性值为null时,可忽略序列化,只需要指定NullValueHandling即可,另外有一种场景是,当对象属性值为null时,需要替换为空字符串双引号,如何替换,请点击这里参阅零度的文章。

16、JSON.NET中循环引用的处理方法
有的对象具有循环引用,对象的属性是对象本身,这会导致JSON.NET进入无限死循环,我们需要指定ReferenceLoopHandling打破这种循环引用。

public class Employee
{
    public string Name { get; set; }
    public Employee Manager { get; set; }
}
Employee joe = new Employee { Name = "Joe User" };
Employee mike = new Employee { Name = "Mike Manager" };
joe.Manager = mike;
mike.Manager = mike;
string json = JsonConvert.SerializeObject(joe, Formatting.Indented, new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
Console.WriteLine(json);
{
  "Name": "Joe User",
  "Manager": {
    "Name": "Mike Manager"
  }
}
17、通过ContractResolver指定属性名首字母小写
通常,在.NET中属性采用PascalCase规则(首字母大写),在JavaScript中属性名使用CamelCase规则(首字母小写),我们希望序列化后的JSON字符串符合CamelCase规则,JSON.NET提供的ContractResolver可以设置属性名小写序列化,更灵活的设置请点击这里参阅零度的文章。

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
}
Person person = new Person { FirstName = "Sarah", LastName = "Security" };
string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
});
Console.WriteLine(json);
{
  "firstName": "Sarah",
  "lastName": "Security",
  "fullName": "Sarah Security"
}
18、JSON.NET中通过特性序列化枚举类型
public enum UserStatus { NotConfirmed, Active, Deleted }

public class User
{
    public string UserName { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    public UserStatus Status { get; set; }
}
默认情况下JSON.NET针对枚举类型输出对应的INT值,如果需要输出具有语义的字符串,可指定JsonConverter的值为StringEnumConverter类型。

User user = new User { UserName = @"零度编程", Status = UserStatus.Deleted };
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);
{
  "UserName": "零度编程",
  "Status": "Deleted"
}
19、指定需要序列化的属性
通过JsonProperty指定哪些字段应该被序列化,需要序列化则标记,不需要序列化则取消标记。

[JsonObject(MemberSerialization.OptIn)]
public class File
{
    //Id不需要序列化
    public Guid Id { get; set; }

    [JsonProperty]
    public string Name { get; set; }

    [JsonProperty]
    public int Size { get; set; }
}
File file = new File
{
    Id = Guid.NewGuid(),
    Name = "xcode.pdf",
    Size = 50 * 1024
};
string json = JsonConvert.SerializeObject(file, Formatting.Indented);
Console.WriteLine(json);
{
  "Name": "xcode.pdf",
  "Size": 51200
}
20、序列化对象时指定属性名
序列化对象时,可标记属性的JsonProperty特性,并指定需要序列化为JSON时应有的属性名。

public class Videogame
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("release_date")]
    public DateTime ReleaseDate { get; set; }
}
Videogame starcraft = new Videogame
{
    Name = "Starcraft",
    ReleaseDate = new DateTime(1998, 1, 1)
};
string json = JsonConvert.SerializeObject(starcraft, Formatting.Indented);
Console.WriteLine(json);
{
  "name": "Starcraft",
  "release_date": "1998-01-01T00:00:00"
}
21、序列化时指定属性在JSON中的顺序
public class Person
{
    [JsonProperty(Order = 2)]
    public string FirstName { get; set; }

    [JsonProperty(Order = 1)]
    public string LastName { get; set; }
}
Person person = new Person { FirstName = "零度", LastName = "编程" };
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(json);
{
  "LastName": "编程",
  "FirstName": "零度"
}
22、反序列化指定属性是否必须有值必须不为null
在反序列化一个JSON时,可通过JsonProperty特性的Required指定反序列化行为,当反序列化行为与指定的行为不匹配时,JSON.NET将抛出异常,Required是枚举,Required.Always表示属性必须有值切不能为null,Required.AllowNull表示属性必须有值,但允许为null值。

public class Videogame
{
    [JsonProperty(Required = Required.Always)]
    public string Name { get; set; }

    [JsonProperty(Required = Required.AllowNull)]
    public DateTime? ReleaseDate { get; set; }
}
string json = @"{
    ‘Name‘: ‘Starcraft III‘,
    ‘ReleaseDate‘: null
  }";
Videogame starcraft = JsonConvert.DeserializeObject<Videogame>(json);
Console.WriteLine(starcraft.Name);
Starcraft III
23、通过特性指定null值忽略序列化
public class Vessel
{
    public string Name { get; set; }
    public string Class { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public DateTime? LaunchDate { get; set; }
}
Vessel vessel = new Vessel { Name = "Red October", Class = "Typhoon" };
string json = JsonConvert.SerializeObject(vessel, Formatting.Indented);
Console.WriteLine(json);
{
  "Name": "Red October",
  "Class": "Typhoon"
}
24、忽略不需要序列化的属性
并不是对象所有属性都要参与序列化,我们可以使用JsonIgnore特性排除不需要序列化的属性,下面示例中的PasswordHash将被忽略。

public class Account
{
    public string FullName { get; set; }
    public string EmailAddress { get; set; }
    [JsonIgnore]
    public string PasswordHash { get; set; }
}
Account account = new Account
{
    FullName = "admin",
    EmailAddress = "[email protected]",
    PasswordHash = "VHdlZXQgJ1FASmFtZXNOSw=="
};
string json = JsonConvert.SerializeObject(account);
Console.WriteLine(json);
{"FullName":"admin","EmailAddress":[email protected]}
25、通过特性指定属性的默认序列化值
当属性没有赋值时,默认值一般是null或者0,我们可通过DefaultValue特性改变默认值,可用指定的字符替换,而不是输出null。

public class Customer
{
    public string FirstName { get; set; }
    [DefaultValue("")]
    public string LastName { get; set; }
}
{"FirstName":null,"LastName":""}
26、序列化或反序列化时指定日期时间格式
JSON.NET中提供一个名为JsonSerializerSettings的设置对象,可通过此对象设置很多序列化和反序列化的行为,如果要设置JSON.NET序列化输出的日期时间格式,只需要指定格式化字符串即可。默认序列化行为,日期时间格式如下:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime CreateDate { get; set; }
}
var custom = new Customer { FirstName = "零度", LastName = "编程", CreateDate = DateTime.Now };
string json = JsonConvert.SerializeObject(custom, Formatting.Indented);
Console.WriteLine(json);
{
  "FirstName": "零度",
  "LastName": "编程",
  "CreateDate": "2015-08-24T17:19:39.0227502+08:00"
}
通过JsonSerializerSettings的DateFormatString属性指定日期时间格式:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(custom, settings);
Console.WriteLine(json);
{
  "FirstName": "零度",
  "LastName": "编程",
  "CreateDate": "2015-08-24 17:23:56"
}
27、JSON字符串格式化
默认情况下通过JsonConvert.SerializeObject(object value)序列化后的JSON是压缩格式,为了便于阅读,通常需要将JSON字符串格式化处理。

var value = new Customer { FirstName = "零度", LastName = "编程"};
string json = JsonConvert.SerializeObject(value);
Console.WriteLine(json);
{"FirstName":"零度","LastName":"编程"}
以上为指定格式化,将输出压缩版JSON字符串,可通过Formatting.Indented指定格式化输出。

string json = JsonConvert.SerializeObject(value, Formatting.Indented);
Console.WriteLine(json);
{
  "FirstName": "零度",
  "LastName": "编程"
}
也可以指定JsonSerializerSettings对象的Formatting值为Formatting.Indented进行格式化,与上面的结果等效。

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(value, settings);
Console.WriteLine(json);

 

以上是关于json.net使用说明二的主要内容,如果未能解决你的问题,请参考以下文章

二代身份证号码编码规则

染色体基因芯片分析和第二代测序应用的区别

带有JSONPath的JSON.NET SelectToken

中国移动怎么申请随机密码

二代下机文件在Integrative Genomics Viewer中实现reads可视化的流程

Android 逆向加壳技术简介 ( 动态加载 | 第一代加壳技术 - DEX 整体加固 | 第二代加壳技术 - 函数抽取 | 第三代加壳技术 - VMP / Dex2C | 动态库加壳技术 )