c# – 如何使用Json.NET对PropertyInfo进行一般反序列化?
我需要使用Json.NET序列化许多不同的对象.我真的无法控制所提供的对象,所以我通常使用
TypeNameHandling.All进行序列化和反序列化.
但是,其中一些对象无法反序列化.具体来说,我得到一些System.Reflection.RuntimePropertyInfo类型.我想以标准化的方式处理这些问题,因为我不知道反序列化时的目标类型.只要输出对象类型正确,我也不在乎. 我已尝试将CustomCreationConverter类型转换为在JsonSerializerSettings中定义的PropertyInfo.但是,即使CanConvert()返回true,也不会使用CustomCreationConverter的ReadJson(). 最终结果就像我从未使用过CustomCreationConverter一样:
我需要CustomCreationConverter来处理ReadJson,以便我可以自己手动搜索PropertyInfo. 经过更多调查后,似乎我正在添加到JsonSerializerSettings的转换器根本没有被使用.如果我使用包含JsonConverter的Type和集合的DeserializeObject重载,则将使用Converter.我不确定转换器提供给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. } } } 解决方法
假设您需要符合的API必须输入/输出PropertyInfo对象,您可以删除转换器并使用新类来仅保存重新创建对象所需的信息.
private class PropertyInfoData { public string TypeName { get; set; } public string PropertyName { get; set; } public static PropertyInfoData FromProperty(PropertyInfo p) { return new PropertyInfoData() { TypeName = p.DeclaringType.AssemblyQualifiedName,PropertyName = p.Name,}; } public PropertyInfo ToProperty() { return Type.GetType(this.TypeName).GetProperty(this.PropertyName); } } 然后你可以像这样对它进行反序列化: var jsonSerializerSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All,//Converters = new JsonConverter[] { new PropertyInfoConverter(),}; var propertyInfo = typeof(Test).GetProperty("Name"); var serialized = JsonConvert.SerializeObject(PropertyInfoData.FromProperty(propertyInfo),jsonSerializerSettings); var deserialized = ((PropertyInfoData)JsonConvert.DeserializeObject(serialized,jsonSerializerSettings)).ToProperty(); 这是一个非常粗糙的(读取方法不是非常强大)示例使用转换器: public class PropertyInfoConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override bool CanConvert(Type objectType) { return typeof(PropertyInfo).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader,JsonSerializer serializer) { string propertyName = null; string assemblyName = null; string typeName = null; while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { string value = reader.Value.ToString(); switch (reader.Value.ToString()) { case "Name": if (reader.Read()) { propertyName = reader.Value.ToString(); } break; case "AssemblyName": if (reader.Read()) { assemblyName = reader.Value.ToString(); } break; case "ClassName": if (reader.Read()) { typeName = reader.Value.ToString(); } break; } } } return Type.GetType(typeName + "," + assemblyName).GetProperty(propertyName); } /// <inheritdoc /> public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) { // When the property "CanWrite" returns false this method is never expected to be called. throw new NotImplementedException(); } } 注意,为了强制deserialize方法使用自定义转换器,你应该像这样调用它的泛型版本: var deserialized = JsonConvert.DeserializeObject<PropertyInfo>(serialized,jsonSerializerSettings); 在你的例子中也是如此,这就是为什么你没有达到你的断点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |