如何使用 JsonConverter 在 System.Text.Json.JsonSerializer.Serialize() 中排除属性被序列化 [英] How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter

查看:30
本文介绍了如何使用 JsonConverter 在 System.Text.Json.JsonSerializer.Serialize() 中排除属性被序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在使用 System.Text.Json.JsonSerializer 进行序列化时能够排除属性.我不想在任何地方使用 JsonIgnore 属性来执行此操作.我希望能够仅通过某种目前不存在的 Fluent API 来定义我想在序列化期间排除的属性.

I want to be able to exclude a property when serializing using System.Text.Json.JsonSerializer. I don't want to use a JsonIgnore attribute everywhere I want to do this. I would like to be able to define the properties I want to exclude during serialization only, via some kind of Fluent API, which currently does not exist.

我能找到的唯一选项是定义一个 JsonConverter 并将其添加到我传递给 Serialize() 方法的 JsonSerializerOptions 上的转换器列表中像这样:

The only option I was able to find is to define a JsonConverter and add it to the list of Converters on the JsonSerializerOptions that I pass to the Serialize() method like so:

var options = new JsonSerializerOptions();
options.Converters.Add(new BookConverter());
json = JsonSerializer.Serialize(book, options);

在 JsonConverter 中,我必须使用 Utf8JsonWriter 自己编写整个 JSON 表示,不包括我不想序列化的属性.这是很多工作才能排除属性.虽然 JsonConverter 是来自 .NET 团队的一个很好的可扩展性特性,但它对于我的用例来说太低级了.有没有人知道有什么其他方法可以在不必自己写出 JSON 表示的情况下实现属性的排除?

In the JsonConverter I would have to write the entire JSON representation myself using a Utf8JsonWriter, excluding the property I don't want to serialize. This is a lot of work to just be able to exclude a property. While the JsonConverter is a great extensibility feature from the .NET team, its just too low-level for my use case. Does anyone know of any other way to acheive the exclusion of the property without having to write out the JSON representation myself?

我不想做以下事情:

  • 使用属性,或在运行时动态添加属性
  • 将属性的访问修饰符更改为 privateprotected
  • 使用 3rd 方库,因为如果我使用 Json.NET,我的问题是可以解决的.

示例:

class Program
{
    void Main()
    {
        // We want to serialize Book but to ignore the Author property
        var book = new Book() { Id = 1, Name = "Calculus", Author = new Author() };

        var json = JsonSerializer.Serialize(book);
        // Default serialization, we get this:
        // json = { "Id": 1, "Name": "Calculus", "Author": {} }

        // Add our custom converter to options and pass it to the Serialize() method
        var options = new JsonSerializerOptions();
        options.Converters.Add(new BookConverter());
        json = JsonSerializer.Serialize(book, options);
        // I want to get this:
        // json = { Id: 1, Name: "Calculus" }
    }
}

public class Author { }

public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Author Author { get; set; }
}

public class BookConverter : JsonConverter<Book>
{
    public override Book Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // Use default implementation when deserializing (reading)
        return JsonSerializer.Deserialize<Book>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, Book value, JsonSerializerOptions options)
    {
        // Serializing. Here we have to write the JSON representation ourselves
        writer.WriteStartObject();

        writer.WriteNumber("Id", value.Id);
        writer.WriteString("Name", value.Name);
        // Don't write Author so we can exclude it

        writer.WriteEndObject();
    }
}

推荐答案

所以我偶然发现了一篇文章,它演示了如何在新的 System.Text 中使用 JsonDocument 对象.Json 命名空间,它是 Fluent API 的次佳选择.以下是如何解决这个问题.

So I happened to stumble upon an article that demonstrates how to use the JsonDocument object in the new System.Text.Json namespace and it is the next best thing to a Fluent API. Here is how this question can be solved.

BookConverter.Write() 方法:

The BookConverter.Write() method:

public override void Write(Utf8JsonWriter writer, Book value, JsonSerializerOptions options)
{
    writer.WriteStartObject();

    using (JsonDocument document = JsonDocument.Parse(JsonSerializer.Serialize(value)))
    {
        foreach (var property in document.RootElement.EnumerateObject())
        {
            if (property.Name != "Author")
                property.WriteTo(writer);
        }
    }

    writer.WriteEndObject();
}

这篇关于如何使用 JsonConverter 在 System.Text.Json.JsonSerializer.Serialize() 中排除属性被序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆