Мне нужно сериализовать множество разных объектов с помощью Json.NET. Я действительно не контролирую предоставляемые объекты, поэтому я обобщаю и де-сериализую с помощью TypeNameHandling.All.Как я могу в целом десериализовать PropertyInfo с помощью Json.NET?
Однако некоторые из этих объектов нельзя де-сериализовать. В частности, я получаю некоторые типы System.Reflection.RuntimePropertyInfo. Я бы хотел обработать их стандартизованным образом, поскольку я не знал о типе цели во время де-сериализации. Меня также не волнует, если тип выходного объекта верен.
Я попытался ввести CustomCreationConverter в PropertyInfo, который определен в JsonSerializerSettings. Однако, несмотря на то, что CanConvert() возвращает true, ReadJson() CustomCreationConverter никогда не используется.
Конечный результат такой же, как если бы я никогда не использовал CustomCreationConverter:
ISerializable типа «System.Reflection.RuntimePropertyInfo» не иметь действительный конструктор. Чтобы правильно реализовать ISerializable, должен присутствовать конструктор , который принимает параметры SerializationInfo и StreamingContext .
Мне нужен CustomCreationConverter для обработки ReadJson, чтобы я мог вручную самостоятельно искать PropertyInfo.
После того, как выяснилось, что конвертеры, которые я добавляю в JsonSerializerSettings, вообще не используются. Если я использую перегрузку DeserializeObject, которая включает в себя тип и коллекцию JsonConverter, конвертер будет использоваться. Я не уверен, что для конвертеров, поставляемых в JsonSerializerSettings, используются, но я бы ожидал, что они будут работать так, как я намереваюсь в этой ситуации.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace Json
{
class Program
{
static void Main(string[] args)
{
var jsonSerializerSettings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
Converters = new JsonConverter[] { new PropertyInfoConverter(), },
};
var propertyInfo = typeof(Test).GetProperty("Name");
var serialized = JsonConvert.SerializeObject(propertyInfo, jsonSerializerSettings);
var deserialized = JsonConvert.DeserializeObject(serialized, jsonSerializerSettings);
}
}
public class Test
{
public string Name { get; set; }
}
public class PropertyInfoConverter : CustomCreationConverter<PropertyInfo>
{
public override bool CanConvert(Type objectType)
{
return typeof(PropertyInfo).IsAssignableFrom(objectType);
}
public override PropertyInfo Create(Type objectType)
{
return null;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return null; // This is never invoked, but is where I would attempt to find the PropertyInfo via Reflection searching.
}
}
}
Зачем вам нужно сериализовать весь объект PropertyInfo? Недостаточно ли имени свойства? Это может быть сложно и сложно, так как PropertyInfo ссылается на Type и Type имеет ссылку на Assembly и Assembly, имеет множество разных ссылок на другие объекты ... –
В частности, это для ввода нового кэширующего провайдера в очень старую устаревшую систему.Сериализация - это требование механизма кэширования нового провайдера. Поставщик должен повторить действия предыдущего провайдера дословно в отношении доступа к кэшу. –
Возможно, вы должны упомянуть об исключении 'ISerializable type 'System.Reflection.RuntimePropertyInfo' не имеет допустимого конструктора. Чтобы правильно реализовать ISerializable, должен присутствовать конструктор, который принимает параметры SerializationInfo и StreamingContext. Путь '', строка 1, позиция 287.' –