.NET 6中System.Text.Json的七个特性

作者:Oleg?Kyrylchuk 时间:2024-05-02 17:20:02 

忽略循环引用

在 .NET 5 中,如果存在循环依赖, 那么序列化的时候会抛出异常, 而在 .NET 6 中, 你可以选择忽略它。

Category dotnet = new()
{
   Name = ".NET 6",
};
Category systemTextJson = new()
{
   Name = "System.Text.Json",
   Parent = dotnet
};
dotnet.Children.Add(systemTextJson);

JsonSerializerOptions options = new()
{
   ReferenceHandler = ReferenceHandler.IgnoreCycles,
   WriteIndented = true
};

string dotnetJson = JsonSerializer.Serialize(dotnet, options);
Console.WriteLine($"{dotnetJson}");

public class Category
{
   public string Name { get; set; }
   public Category Parent { get; set; }
   public List<Category> Children { get; set; } = new();
}

// 输出:
// {
//   "Name": ".NET 6",
//   "Parent": null,
//   "Children": [
//     {
//       "Name": "System.Text.Json",
//       "Parent": null,
//       "Children": []
//     }
//   ]
// }

序列化和反序列化通知

在 .NET 6 中,System.Text.Json 公开序列化和反序列化的通知。

有四个新接口可以根据您的需要进行实现:

  • IJsonOnDeserialized

  • IJsonOnDeserializing

  • IJsonOnSerialized

  • IJsonOnSerializing

Product invalidProduct = new() { Name = "Name", Test = "Test" };
JsonSerializer.Serialize(invalidProduct);
// The InvalidOperationException is thrown

string invalidJson = "{}";
JsonSerializer.Deserialize<Product>(invalidJson);
// The InvalidOperationException is thrown

class Product : IJsonOnDeserialized, IJsonOnSerializing, IJsonOnSerialized
{
   public string Name { get; set; }

public string Test { get; set; }

public void OnSerialized()
   {
       throw new NotImplementedException();
   }

void IJsonOnDeserialized.OnDeserialized() => Validate(); // Call after deserialization
   void IJsonOnSerializing.OnSerializing() => Validate();   // Call before serialization

private void Validate()
   {
       if (Name is null)
       {
           throw new InvalidOperationException("The 'Name' property cannot be 'null'.");
       }
   }
}

 序列化支持属性排序

在 .NET 6 中, 添加了 JsonPropertyOrderAttribute 特性,允许控制属性的序列化顺序,以前,序列化顺序是由反射顺序决定的。

Product product = new()
{
   Id = 1,
   Name = "Surface Pro 7",
   Price = 550,
   Category = "Laptops"
};

JsonSerializerOptions options = new() { WriteIndented = true };
string json = JsonSerializer.Serialize(product, options);
Console.WriteLine(json);

class Product : A
{
   [JsonPropertyOrder(2)]  
   public string Category { get; set; }

[JsonPropertyOrder(1)]  
   public decimal Price { get; set; }

public string Name { get; set; }  

[JsonPropertyOrder(-1)]  
   public int Id { get; set; }
}

class A
{
   public int Test { get; set; }
}

// 输出:
// {
//   "Id": 1,
//   "Name": "Surface Pro 7",
//   "Price": 550,
//   "Category": "Laptops"
// }

使用 Utf8JsonWriter 编写 JSON

.NET 6 增加了 System.Text.Json.Utf8JsonWriter,你可以方便的用它编写原始Json。

JsonWriterOptions writerOptions = new() { Indented = true, };

using MemoryStream stream = new();
using Utf8JsonWriter writer = new(stream, writerOptions);

writer.WriteStartObject();
writer.WriteStartArray("customJsonFormatting");
foreach (double result in new double[] { 10.2, 10 })
{
   writer.WriteStartObject();
   writer.WritePropertyName("value");
   writer.WriteRawValue(FormatNumberValue(result), skipInputValidation: true);
   writer.WriteEndObject();
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();

string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);

static string FormatNumberValue(double numberValue)
{
   return numberValue == Convert.ToInt32(numberValue)
       ? numberValue.ToString() + ".0"
       : numberValue.ToString();
}

// 输出:
// {
//    "customJsonFormatting": [
//      {
//        "value": 10.2
//      },
//      {
//        "value": 10.0
//      }
//  ]
// }

IAsyncEnumerable 支持

在 .NET 6 中, System.Text.Json 支持 IAsyncEnumerable

static async IAsyncEnumerable<int> GetNumbersAsync(int n)
{
   for (int i = 0; i < n; i++)
   {
       await Task.Delay(1000);
       yield return i;
   }
}
// Serialization using IAsyncEnumerable
JsonSerializerOptions options = new() { WriteIndented = true };
using Stream 输出Stream = Console.OpenStandard输出();
var data = new { Data = GetNumbersAsync(5) };
await JsonSerializer.SerializeAsync(输出Stream, data, options);
// 输出:
// {
//    "Data": [
//      0,
//      1,
//      2,
//      3,
//      4
//  ]
// }

// Deserialization using IAsyncEnumerable
using MemoryStream memoryStream = new(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));
// Wraps the UTF-8 encoded text into an IAsyncEnumerable<T> that can be used to deserialize root-level JSON arrays in a streaming manner.
await foreach (int item in JsonSerializer.DeserializeAsyncEnumerable<int>(memoryStream))
{
   Console.WriteLine(item);
}
// 输出:
// 0
// 1
// 2
// 3
// 4

IAsyncEnumerable 的序列化的动图。

.NET 6中System.Text.Json的七个特性

序列化支持流

在 .NET 6 中, 序列化和反序列化支持流。

string json = "{\"Value\":\"Deserialized from stream\"}";
byte[] bytes = Encoding.UTF8.GetBytes(json);

// Deserialize from stream
using MemoryStream ms = new MemoryStream(bytes);
Example desializedExample = JsonSerializer.Deserialize<Example>(ms);
Console.WriteLine(desializedExample.Value);
// 输出: Deserialized from stream

// ==================================================================

// Serialize to stream
JsonSerializerOptions options = new() { WriteIndented = true };
using Stream 输出Stream = Console.OpenStandard输出();
Example exampleToSerialize = new() { Value = "Serialized from stream" };
JsonSerializer.Serialize<Example>(输出Stream, exampleToSerialize, options);
// 输出:
// {
//    "Value": "Serialized from stream"
// }

class Example
{
   public string Value { get; set; }
}

像 DOM 一样使用 JSON

.NET 6 添加了下面的新类型, 支持像操作 DOM 一样访问 Json 元素。

  • JsonArray

  • JsonNode

  • JsonObject

  • JsonValue

// Parse a JSON object
JsonNode jNode = JsonNode.Parse("{\"Value\":\"Text\",\"Array\":[1,5,13,17,2]}");
string value = (string)jNode["Value"];
Console.WriteLine(value); // Text
                         // or
value = jNode["Value"].GetValue<string>();
Console.WriteLine(value); // Text

int arrayItem = jNode["Array"][1].GetValue<int>();
Console.WriteLine(arrayItem); // 5
                             // or
arrayItem = jNode["Array"][1].GetValue<int>();
Console.WriteLine(arrayItem); // 5

// Create a new JsonObject
var jObject = new JsonObject
{
   ["Value"] = "Text",
   ["Array"] = new JsonArray(1, 5, 13, 17, 2)
};
Console.WriteLine(jObject["Value"].GetValue<string>());  // Text
Console.WriteLine(jObject["Array"][1].GetValue<int>());  // 5

// Converts the current instance to string in JSON format
string json = jObject.ToJsonString();
Console.WriteLine(json); // {"Value":"Text","Array":[1,5,13,17,2]}

以上所述是小编给大家介绍的.NET 6中System.Text.Json的七个特 * 的支持!

来源:https://mp.weixin.qq.com/s/ggEeqm_e4i7d4w-_44mPgA

标签:.NET6,System,Text,Json,特性
0
投稿

猜你喜欢

  • (X)HTML Strict 下的嵌套规则

    2008-03-08 18:39:00
  • 让网站容易被发现

    2009-04-20 20:35:00
  • Python如何筛选序列中的元素的方法实现

    2021-06-12 03:31:51
  • python如何实现数据的线性拟合

    2023-10-08 01:56:01
  • Pandas把dataframe或series转换成list的方法

    2022-03-24 23:05:02
  • MySQL数据库基本SQL语句教程之高级操作

    2024-01-24 08:08:11
  • ThinkPHP文件缓存类代码分享

    2024-05-22 10:02:11
  • Python iter()函数用法实例分析

    2022-11-01 00:00:01
  • Python3下错误AttributeError: ‘dict’ object has no attribute’iteritems‘的分析与解决

    2023-04-21 05:52:45
  • Python中tqdm的使用和例子

    2022-05-31 23:59:32
  • Python lambda表达式filter、map、reduce函数用法解析

    2022-03-30 03:52:31
  • python 判断txt每行内容中是否包含子串并重新写入保存的实例

    2023-11-28 06:34:56
  • Python字符串的创建和驻留机制详解

    2022-07-07 18:49:17
  • 儿童编程python入门

    2021-03-12 15:25:06
  • asp数字或者字符排序函数代码

    2011-02-24 11:00:00
  • asp任何取得多个表单的值

    2008-04-15 15:31:00
  • Python使用plt.boxplot() 参数绘制箱线图

    2022-06-03 16:30:09
  • python实现的多线程端口扫描功能示例

    2023-02-02 10:18:29
  • Anaconda安装pytorch和paddle的方法步骤

    2021-04-17 18:21:59
  • MySQL多表查询的具体实例

    2024-01-22 00:13:20
  • asp之家 网络编程 m.aspxhome.com