![](/img/trans.png)
[英]How to use System.Text.Json.JsonSerializer.Serialize in Metalama
[英]How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter
我希望能夠在使用 System.Text.Json.JsonSerializer 進行序列化時排除屬性。 我不想在任何我想這樣做的地方使用JsonIgnore
屬性。 我希望能夠通過某種當前不存在的 Fluent API 來定義我想僅在序列化期間排除的屬性。
我能找到的唯一選擇是定義一個JsonConverter
並將其添加到我傳遞給 Serialize() 方法的JsonSerializerOptions
上的轉換器列表中,如下所示:
var options = new JsonSerializerOptions();
options.Converters.Add(new BookConverter());
json = JsonSerializer.Serialize(book, options);
在 JsonConverter 中,我必須自己使用Utf8JsonWriter
編寫整個 JSON 表示,不包括我不想序列化的屬性。 僅僅能夠排除一個屬性需要做很多工作。 雖然 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();
}
}
提取描述所需 object 結構的接口。
public interface IBook { public int Id { get; set; } public string Name { get; set; } }
在原版 class class Book: IBook
使用string Serialize(object value, Type inputType, JsonSerializerOptions options = null);
的后續重載
json = JsonSerializer.Serialize(book, typeof(IBook), options);
如果要序列化Books
數組(復數),則需要將typeof(IEnumerable<IBook>)
作為參數傳遞。
如果您無權訪問原始Book
class,這將非常有用。
創建LiteBook
class:
public class LiteBook { public int Id { get; set; } public string Name { get; set; } }
創建映射配置:
var config = new MapperConfiguration(cfg => { cfg.CreateMap<Book, LiteBook>(); });
Map 並序列化
json = JsonSerializer.Serialize(new Mapper(config).Map<LiteBook>(book), options)
因此,我偶然發現了一篇文章,該文章演示了如何在新的System.Text.Json
命名空間中使用JsonDocument
object,它是 Fluent ZDB974238714CA8DE634A7CE1D083A4 的下一個最佳選擇這是如何解決這個問題的。
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();
}
您可以簡單地忽略這樣的屬性:
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public Author Author { get; set; }
}
您可以嘗試使用以下方法:
public static object ConvertToObjectWithoutListedProperties<T>(
this T objectToTransform,
string[] propertiesToIgnore)
{
var type = objectToTransform.GetType();
var returnClass = new ExpandoObject() as IDictionary<string, object>;
foreach (var propertyInfo in type.GetProperties())
if (!propertiesToIgnore.Contains(propertyInfo.Name))
returnClass.Add(propertyInfo.Name,
propertyInfo.GetValue(objectToTransform));
return returnClass;
}
致謝:“ 從 object 中刪除 null 屬性”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.