Некоторое время назад мне понадобился собственный универсальный json-конвертер, который автоматически преобразовывал бы объект в коллекцию, если это необходимо.Мое решение было:
public class SingleValueCollectionConverter<T> : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.TokenType == JsonToken.StartArray ? serializer.Deserialize(reader, objectType) : new List<T> { (T)serializer.Deserialize(reader, typeof(T)) };
}
public override bool CanConvert(Type objectType)
{
return true;
}
}
Это работало нормально, пока у меня не возникла ситуация, когда мне нужно было использовать его для свойства с универсальным типом.У меня есть ошибка при использовании этого как это:
[JsonConverter(typeof(SingleValueCollectionConverter<TData>))]
public List<TData> Data { get; set; }
Оказалось, что общие параметры не могут появляться в объявлениях атрибутов.Я нашел этот запрос на получение доступа к newtonsoftJsonConverter - https://github.com/JamesNK/Newtonsoft.Json/issues/1332, где было предложено решение, но оно не было одобрено автором.Итак, я создал неуниверсальный конвертер, который работает как универсальный с помощью рефлексии:
public class SingleValueCollectionConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
foreach (var prop in objectType.GetProperties())
{
var type = prop.PropertyType;
if (!type.IsClass)
continue;
var destination = Activator.CreateInstance(objectType);
var result = reader.TokenType == JsonToken.StartArray
? serializer.Deserialize(reader, objectType)
: new List<object> { serializer.Deserialize(reader, type) };
return Mapper.Map(result, destination, result.GetType(), destination.GetType());
}
return null;
}
public override bool CanConvert(Type objectType)
{
return true;
}
}
Используя вот так:
[JsonConverter(typeof(SingleValueCollectionConverter))]
public List<TData> Data { get; set; }
Работает нормально, но, может быть, у кого-то лучшерешение.Буду признателен за любые предложения.