如何使用JsonConverter从System.Text.Json.JsonSerializer.Serialize()中排除要序列化的属性 [英] How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter
问题描述
我希望能够在使用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
上的Converters列表中,如下所示:
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?
我不想执行以下操作:
- 使用属性,或在运行时动态添加属性
- 将属性的访问修饰符更改为
private
或protected
- 使用3rd party库,因为如果使用Json.NET,我的问题就可以解决.
- Use an attribute, or dynamically add an attribute at runtime
- Change the access modifier of the property to something like
private
orprotected
- Use a 3rd party library, as my issue is solvable if I use 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.Json
命名空间中使用JsonDocument
对象,这是下一个最好的选择流利的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屋!