Tar*_*her 11 c# serialization json .net-core
我希望能够在使用 System.Text.Json.JsonSerializer 进行序列化时排除属性。我不想JsonIgnore在我想这样做的任何地方都使用属性。我希望能够仅通过某种目前不存在的 Fluent API 来定义我想在序列化期间排除的属性。
我能找到的唯一选项是定义一个JsonConverter并将其添加到JsonSerializerOptions我传递给 Serialize() 方法的 Converters 列表中,如下所示:
var options = new JsonSerializerOptions();
options.Converters.Add(new BookConverter());
json = JsonSerializer.Serialize(book, options);
在 JsonConverter 中,我必须自己使用 a 编写整个 JSON 表示Utf8JsonWriter,不包括我不想序列化的属性。仅仅能够排除一个属性就需要做很多工作。虽然 JsonConverter 是 .NET 团队的一个很好的可扩展性功能,但它对于我的用例来说太低级了。有没有人知道有任何其他方法可以在不必自己写出 JSON 表示的情况下实现属性的排除?
我不想做以下事情:
private或protected例子:
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();
    }
}
提取接口,描述所需对象的结构。
public interface IBook
{
    public int Id { get; set; }
    public string Name { get; set; }
}
在原始类上实现它 class Book : IBook
使用以下重载 string Serialize(object value, Type inputType, JsonSerializerOptions options = null);
json = JsonSerializer.Serialize(book, typeof(IBook), options);
如果要序列化Books(复数)数组,则需要typeof(IEnumerable<IBook>)作为参数传递。
如果您无权访问原始Book类,这将很有用。
创建LiteBook类:
public class LiteBook
{
    public int Id { get; set; }
    public string Name { get; set; }
}
创建映射配置:
var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<Book, LiteBook>();
});
映射并序列化
json = JsonSerializer.Serialize(new Mapper(config).Map<LiteBook>(book), options)
所以我偶然发现了一篇文章,它演示了如何JsonDocument在新System.Text.Json命名空间中使用对象,它是 Fluent API 的次佳选择。下面是如何解决这个问题。
BookConverter.Write() 方法:
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();
}
.Net 7 使得更灵活、动态地控制哪些属性被序列化成为可能。请参阅此处的官方博客文章:
| 归档时间: | 
 | 
| 查看次数: | 4092 次 | 
| 最近记录: |