Newtonsoft.Json

Newtonsoft.Json是一款强大的JSON序列化和反序列化库,本文详细介绍了其基本使用、特性,包括TypeNameHandling设置、JsonConvert、JsonConverter等,帮助开发者更好地理解和运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

引言

 1、简单使用

1.1、官方案例

 1.1.1、TypeNameHandling设置

1.1.2、NullValueHandling设置

1.1.3、Formatting设置

1.1.4、ObjectCreationHandling设置

 1.2、JsonConvert

2、特性

2.1、默认模式[JsonObject(MemberSerialization.OptIn/OptOut)]

 2.2、序列化为集合JsonArrayAttribute/JsonDictionaryAttribute

2.3、序列化该元素JsonProperty

2.4、忽略元素JsonIgnoreAttribute

2.5、序列化方式JsonConverter

2.6、将意外元素存到集合JsonExtensionData

 2.7、指定构造函数JsonConstructor

2.8、默认值DefaultValue

3、回调函数

4、错误处理

4.1、OnErrorAttribute

引言

Newtonsoft.Json是一款高性能Json序列化和解析工具,开源免费!它使得配置文件的保存和读取变得简单,提供对类属性和字段的序列化控制,以及在序列化过程中或完成后执行相应的方法。

 1、简单使用

1.1、官方案例

序列化:

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };

string json = JsonConvert.SerializeObject(product,Formatting.Indented);//格式化Formatting.Indented
// {
//   "Name": "Apple",
//   "Expiry": "2008-12-28T00:00:00",
//   "Sizes": [
//     "Small"
//   ]
// }

 1.1.1、TypeNameHandling设置

        序列化和反序列化时添加JsonSerializerSettings,属性TypeNameHandling设置为TypeNameHandling.All。作用:就是设置Json.NET能够序列化接口或继承类的关键,将TypeNameHandling设置为All后,Json.NET会在序列化后的json文本中附加一个属性说明json到底是从什么类序列化过来的,也可以设置TypeNameHandling为Auto,表示让Json.NET自动判断是否需要在序列化后的json中添加类型属性,如果序列化的对象类型和声明类型不一样的话Json.NET就会在json中添加类型属性,反之就不添加。

        这在抽象类中,不同子类组成的列表中非常有用。对于抽象类Person,继承类:Student、Employee,组成列表List<Person>,反序列化时如果不标记,会报无法创建抽象类实例或接口的错误。这就需要标记其类型。


string str = JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto
            });

1.1.2、NullValueHandling设置

对于空值是否序列化,Ignore:则忽略,默认不忽略,记为如:Age:null。

1.1.3、Formatting设置

Formatting.Indented 文本中自动换行并缩进,可读性更好。默认不格式化。

1.1.4、ObjectCreationHandling设置

控制当使用Jsonconvert.PopulateObject反序列化时,将字符串反序列化到一个现有实例上应该做怎样的操作。

Auto:会以附加的方式添加列表元素,属性直接替换。

Replace:直接替换,不附加。

反序列化:

string json = @"{
  'Name': 'Bad Boys',
  'ReleaseDate': '1995-4-7T00:00:00',
  'Genres': [
    'Action',
    'Comedy'
  ]
}";

Movie m = JsonConvert.DeserializeObject<Movie>(json);

string name = m.Name;
// Bad Boys

 LINQ to Json:

JArray array = new JArray();
array.Add("Manual text");
array.Add(new DateTime(2000, 5, 23));

JObject o = new JObject();
o["MyArray"] = array;

string json = o.ToString();
// {
//   "MyArray": [
//     "Manual text",
//     "2000-05-23T00:00:00"
//   ]
// }

 1.2、JsonConvert

Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "ExpiryDate": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);

 最常用的反序列化方法:

Public method

Static member

DeserializeObject<T>(String)

Deserializes the JSON to the specified .NET type.

Public method

Static member

DeserializeObject<T>(String,JsonConverter[])

Deserializes the JSON to the specified .NET type using a collection of JsonConverter.

Public method

Static member

DeserializeObject<T>(String, JsonSerializerSettings)

Deserializes the JSON to the specified .NET type using JsonSerializerSettings.

2、特性

2.1、默认模式[JsonObject(MemberSerialization.OptIn/OptOut)]

[JsonObject(MemberSerialization.OptIn)]:默认不序列化,成员必须具有 JsonPropertyDataMember 属性才能序列化

[JsonObject(MemberSerialization.OptOut)]:默认都序列化,添加[JsonIgnore]的忽略。

不加特性系统默认是都序列化

//默认不序列化,添加特性的序列化
[JsonObject(MemberSerialization.OptIn)]
public class Person
{
    // "John Smith"
    [JsonProperty]
    public string Name { get; set; }

    // "2000-12-15T22:11:03"
    [JsonProperty]
    public DateTime BirthDate { get; set; }

    // new Date(976918263055)
    [JsonProperty]
    public DateTime LastModified { get; set; }

    // not serialized because mode is opt-in
    public string Department { get; set; }
}
[JsonObject(MemberSerialization.OptOut)]
public class Person
{
    // "John Smith"
    public string Name { get; set; }

    // "2000-12-15T22:11:03"
    public DateTime BirthDate { get; set; }

    // new Date(976918263055)
    public DateTime LastModified { get; set; }

    // not serialized
    [JsonIgnore]
    public string Department { get; set; }
}

 2.2、序列化为集合JsonArrayAttribute/JsonDictionaryAttribute

JsonArrayAttribute 和 JsonDictionaryAttribute 用于指定是否将一个类序列化为该集合类型。

集合属性有多个选项,可自定义应用于集合项的 JsonConverter、类型名称处理和引用处理。

2.3、序列化该元素JsonProperty

JsonPropertyAttribute 有多种用途:

    默认情况下,JSON 属性的名称与 .NET 属性的名称相同。该属性允许自定义名称。

    当成员序列化设置为选择加入时,JsonPropertyAttribute 表示应序列化属性。

    它包括序列化和反序列化中的非公共属性。

    它可用于自定义属性值的类型名称、引用、空值和默认值处理。

    可用于自定义序列化属性名称的命名策略。

    可用于自定义属性的 JsonConverter 集合项、类型名称处理和引用处理。

DataMemberAttribute 可用于替代 JsonPropertyAttribute。

public class Myclass
{
    [JsonProperty("数值")]
    public int number;
}
{"数值":0}

2.4、忽略元素JsonIgnoreAttribute

JsonIgnoreAttribute 忽略属性

将字段或属性排除在序列化之外。

NonSerializedAttribute 可用于替代 JsonIgnoreAttribute。

2.5、序列化方式JsonConverter

JsonConverterAttribute 属性指定了用于转换对象的 JsonConverter。

该属性可以放在类上,也可以放在成员上。如果将该属性放在类上,该属性指定的 JsonConverter 将是该类序列化的默认方式。当属性位于字段或属性上时,指定的 JsonConverter 将始终用于序列化该值。

使用哪个 JsonConverter 的优先级是成员属性,然后是类属性,最后是传递给 JsonSerializer 的任何转换器。

public enum UserStatus
{
    NotConfirmed,
    Active,
    Deleted
}

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

    [JsonConverter(typeof(StringEnumConverter))]
    public UserStatus Status { get; set; }
}
{"UserName":null,"Status":"NotConfirmed"}
而不是
{"UserName":null,"Status":0}

本例显示了 JsonConverterAttribute 应用于一个属性的情况。

要将 JsonConverter 应用于集合中的项,可使用 JsonArrayAttribute、JsonDictionaryAttribute 或 JsonPropertyAttribute,并将 ItemConverterType 属性设置为要使用的转换器类型。

2.6、将意外元素存到集合JsonExtensionData

JsonExtensionDataAttribute 会指示 JsonSerializer 将类型中没有匹配字段或属性的属性反序列化到指定的集合中。在序列化过程中,该集合中的值会写回到实例的 JSON 对象中。

下面示例显示了 JsonExtensionDataAttribute 被应用到一个字段,在反序列化过程中,不匹配的 JSON 属性被添加到字段的集合中。

public class DirectoryAccount
{
    // normal deserialization
    public string DisplayName { get; set; }

    // these properties are set in OnDeserialized
    public string UserName { get; set; }
    public string Domain { get; set; }

    [JsonExtensionData]
    private IDictionary<string, JToken> _additionalData;

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        // SAMAccountName is not deserialized to any property
        // and so it is added to the extension data dictionary
        string samAccountName = (string)_additionalData["SAMAccountName"];

        Domain = samAccountName.Split('\\')[0];
        UserName = samAccountName.Split('\\')[1];
    }

    public DirectoryAccount()
    {
        _additionalData = new Dictionary<string, JToken>();
    }
}
string json = @"{
  'DisplayName': 'John Smith',
  'SAMAccountName': 'contoso\\johns'
}";

DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json);

Console.WriteLine(account.DisplayName);
// John Smith

Console.WriteLine(account.Domain);
// contoso

Console.WriteLine(account.UserName);
// johns

 2.7、指定构造函数JsonConstructor

JsonConstructorAttribute 可指示 JsonSerializer 在反序列化类时使用特定的构造函数。它可用于使用参数化构造函数而不是默认构造函数创建类,或者在有多个参数化构造函数时选择使用哪个特定的构造函数。

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"": ""domain\\username"",
  ""Enabled"": true
}";

User user = JsonConvert.DeserializeObject<User>(json);

Console.WriteLine(user.UserName);
// domain\username

2.8、默认值DefaultValue

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; }
}

3、回调函数

要告诉序列化器在对象的序列化生命周期中应该调用哪些方法,可以用相应的属性(OnSerializingAttribute、OnSerializedAttribute、OnDeserializingAttribute、OnDeserializedAttribute)来装饰方法。

public class SerializationEventTestObject
{
    // 2222
    // This member is serialized and deserialized with no change.
    public int Member1 { get; set; }

    // The value of this field is set and reset during and 
    // after serialization.
    public string Member2 { get; set; }

    // This field is not serialized. The OnDeserializedAttribute 
    // is used to set the member value after serialization.
    [JsonIgnore]
    public string Member3 { get; set; }

    // This field is set to null, but populated after deserialization.
    public string Member4 { get; set; }

    public SerializationEventTestObject()
    {
        Member1 = 11;
        Member2 = "Hello World!";
        Member3 = "This is a nonserialized value";
        Member4 = null;
    }

    [OnSerializing]
    internal void OnSerializingMethod(StreamingContext context)
    {
        Member2 = "This value went into the data file during serialization.";
    }

    [OnSerialized]
    internal void OnSerializedMethod(StreamingContext context)
    {
        Member2 = "This value was reset after serialization.";
    }

    [OnDeserializing]
    internal void OnDeserializingMethod(StreamingContext context)
    {
        Member3 = "This value was set during deserialization";
    }

    [OnDeserialized]
    internal void OnDeserializedMethod(StreamingContext context)
    {
        Member4 = "This value was set after deserialization.";
    }
}
SerializationEventTestObject obj = new SerializationEventTestObject();

Console.WriteLine(obj.Member1);
// 11
Console.WriteLine(obj.Member2);
// Hello World!
Console.WriteLine(obj.Member3);
// This is a nonserialized value
Console.WriteLine(obj.Member4);
// null

string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
// {
//   "Member1": 11,
//   "Member2": "This value went into the data file during serialization.",
//   "Member4": null
// }

Console.WriteLine(obj.Member1);
// 11
Console.WriteLine(obj.Member2);
// This value was reset after serialization.
Console.WriteLine(obj.Member3);
// This is a nonserialized value
Console.WriteLine(obj.Member4);
// null

obj = JsonConvert.DeserializeObject<SerializationEventTestObject>(json);

Console.WriteLine(obj.Member1);
// 11
Console.WriteLine(obj.Member2);
// This value went into the data file during serialization.
Console.WriteLine(obj.Member3);
// This value was set during deserialization
Console.WriteLine(obj.Member4);
// This value was set after deserialization.

4、错误处理

错误事件是 JsonSerializer 中的一个事件处理程序。只要在序列化或反序列化 JSON 时出现异常,就会引发错误事件。与 JsonSerializer 上的所有设置一样,它也可以在 JsonSerializerSettings 上设置,并传递给 JsonConvert 上的序列化方法。

List<string> errors = new List<string>();

List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
      '2009-09-09T00:00:00Z',
      'I am not a date and will error!',
      [
        1
      ],
      '1977-02-20T00:00:00Z',
      null,
      '2000-12-01T00:00:00Z'
    ]",
    new JsonSerializerSettings
    {
        Error = delegate(object sender, ErrorEventArgs args)
        {
            errors.Add(args.ErrorContext.Error.Message);
            args.ErrorContext.Handled = true;
        },
        Converters = { new IsoDateTimeConverter() }
    });

// 2009-09-09T00:00:00Z
// 1977-02-20T00:00:00Z
// 2000-12-01T00:00:00Z

// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
// Unexpected token parsing date. Expected String, got StartArray.
// Cannot convert null value to System.DateTime.

4.1、OnErrorAttribute

public class PersonError
{
    private List<string> _roles;

    public string Name { get; set; }
    public int Age { get; set; }

    public List<string> Roles
    {
        get
        {
            if (_roles == null)
            {
                throw new Exception("Roles not loaded!");
            }

            return _roles;
        }
        set { _roles = value; }
    }

    public string Title { get; set; }

    [OnError]
    internal void OnError(StreamingContext context, ErrorContext errorContext)
    {
        errorContext.Handled = true;
    }
}

 在本例中,如果没有设置角色,访问 Roles 属性时就会出现异常。HandleError 方法会在序列化 Roles 时将错误设置为已处理,并允许 Json.NET 继续序列化该类。

PersonError person = new PersonError
{
    Name = "George Michael Bluth",
    Age = 16,
    Roles = null,
    Title = "Mister Manager"
};

string json = JsonConvert.SerializeObject(person, Formatting.Indented);

Console.WriteLine(json);
//{
//  "Name": "George Michael Bluth",
//  "Age": 16,
//  "Title": "Mister Manager"
//}

NewtonSoft.Json是一个用于处理和操作JSON数据的.NET库。它提供了一些类和方法,使我们能够方便地序列化和反序列化JSON数据,以及查询和修改JSON数据。你可以使用JsonConvert类的DeserializeObject方法将JSON字符串反序列化为具体的对象,例如使用JObject类表示JSON对象,然后使用索引访问属性值。此外,NewtonSoft.Json还提供了JsonSerializerSettings类,用于配置序列化和反序列化的行为,比如转换枚举值为字符串表示,指定日期时间的格式等。另外,你还可以使用Linq to JSON查询语法来查询和操作JSON数据,例如使用JObject.Parse方法将JSON字符串解析为JObject对象,然后使用索引或Linq语法获取属性值。123 #### 引用[.reference_title] - *1* *2* [Newtonsoft.Json基本使用](https://blog.csdn.net/m0_47659279/article/details/119870046)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [C# Newtonsoft.Json用法](https://blog.csdn.net/qq_38693757/article/details/113728350)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

James.TCG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值