Newtonsoft を使用して、空のコレクションを無視するためのカスタム リゾルバーを作成しました。.Netコア3.1の新しいsystem.text.jsonに相当する構成はありますか
2698 次
2 に答える
0
試み
これはあなたが求めているものではないことはわかっていますが、誰かがこれに基づいて構築できるか、いくつかのシナリオに適合する可能性が非常にわずかです。
できたこと
new A()
のオブジェクト
public class A
{
public List<int> NullList {get;set;}
public List<int> EmptyList {get;set;} = new List<int>();
};
になる
{
"EmptyList": null
}
ドキュメンテーション
カスタム コンバーター パターンの 2021 年 2 月 25 日から.NET で JSON シリアル化 (マーシャリング) 用のカスタム コンバーターを作成する方法 には、次のように書かれています。
カスタム コンバーターの作成には、基本パターンとファクトリー パターンの 2 つのパターンがあります。ファクトリ パターンは、列挙型またはオープン ジェネリックを処理するコンバーター用です。基本的なパターンは、非ジェネリックおよびクローズ ジェネリック型用です。たとえば、次の型のコンバーターにはファクトリ パターンが必要です。
- Dictionary<TKey,TValue>
- 列挙型
- リスト
基本パターンで処理できる型の例としては、次のようなものがあります。
- Dictionary<int, string>
- WeekdaysEnum
- リスト
- 日付時刻
- Int32
基本パターンは、1 つの型を処理できるクラスを作成します。ファクトリ パターンは、実行時に必要な特定の型を決定し、適切なコンバーターを動的に作成するクラスを作成します。
私がしたこと
デモ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
#nullable disable
namespace Sandbox4
{
public class A
{
public List<int> NullList {get;set;}
public List<int> EmptyList {get;set;} = new List<int>();
};
public class Program
{
public static void Main()
{
A a = new ();
JsonSerializerOptions options = new ()
{
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = true,
Converters =
{
new IEnumerableTConverter()
}
};
string aJson =
JsonSerializer.Serialize<A>(a, options);
Console.WriteLine(aJson);
}
}
}
コンバータ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Sandbox4
{
// Modified DictionaryTEnumTValueConverter
// from https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0#custom-converter-patterns
public class IEnumerableTConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
{
return false;
}
var realType = typeToConvert.GetGenericTypeDefinition();
if (realType.IsAssignableTo(typeof(IEnumerable<>)))
{
return false;
}
return true;
}
public override JsonConverter CreateConverter(
Type type,
JsonSerializerOptions options)
{
Type generictype = type.GetGenericArguments()[0];
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(ICollectionTConverterInner<,>).MakeGenericType(
new Type[] { type, generictype }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: new object[] { type, options },
culture: null);
return converter;
}
private class ICollectionTConverterInner<T,U> :
JsonConverter<T> where T: IEnumerable<U>
{
private readonly JsonConverter<T> _normalConverter;
public ICollectionTConverterInner(Type type,JsonSerializerOptions options)
{
// For performance, use the existing converter if available.
var existing = new JsonSerializerOptions().GetConverter(type);
if( existing == null ) throw new ApplicationException($"Standard converter for {type} not found.");
_normalConverter = (JsonConverter<T>) existing;
}
public override T Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
// Untested
return _normalConverter.Read(ref reader, typeToConvert, options);
}
public override void Write(
Utf8JsonWriter writer,
T collection,
JsonSerializerOptions options)
{
if(!collection.Any())
{
writer.WriteNullValue();
return;
}
_normalConverter.Write(writer, collection, options);
}
}
}
}
于 2021-04-09T14:44:06.380 に答える