这里发生了一些事情。首先,一个初步的问题:即使没有
TypeConverter应用,您的JSON也不对应于您的class
Foo,它对应于某些包含
Foo属性的容器类,例如:
public class TestClass{ public Foo Foo { get; set; }}
即给定您的JSON字符串,以下将不起作用:
var json = "{"Foo":{"a":true,"b":false,"c":false}}";var foo = JsonConvert.DeserializeObject<Foo>(json);
但是以下内容将:
var test = JsonConvert.DeserializeObject<TestClass>(json);
我怀疑这只是问题中的一个错误,因此我假设您要反序列化包含property的类
Foo。
您看到的主要问题是Json.NET
将尝试使用TypeConverter
if(如果存在)将要序列化的类转换为JSON字符串。从文档:
基本类型
.Net :(
TypeConverter可转换为String)
JSON:String
但是在您的JSON中,
Foo它不是JSON字符串,而是JSON 对象 ,因此一旦应用类型转换器,反序列化将失败。嵌入的字符串如下所示:
{"Foo":"{"a":true,"b":false,"c":false}"}
请注意如何将所有引号转义。并且即使您更改了
Foo对象的JSON格式以与此匹配,您的反序列化仍将失败,因为
TypeConverterand和Json.NET尝试递归调用彼此。
因此,您需要做的是全局禁用
TypeConverterJson.NET的使用,并退回到默认序列化,同时保留
TypeConverter在所有其他情况下的使用。这有点棘手,因为没有可用于禁止使用类型转换器的Json.NET属性,而是需要一个特殊的协定解析器以及一个特殊的协定解析器
JsonConverter来使用它:
public class NoTypeConverterJsonConverter<T> : JsonConverter{ static readonly IContractResolver resolver = new NoTypeConverterContractResolver(); class NoTypeConverterContractResolver : DefaultContractResolver { protected override JsonContract CreateContract(Type objectType) { if (typeof(T).IsAssignableFrom(objectType)) { var contract = this.CreateObjectContract(objectType); contract.Converter = null; // Also null out the converter to prevent infinite recursion. return contract; } return base.CreateContract(objectType); } } public override bool CanConvert(Type objectType) { return typeof(T).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return JsonSerializer.CreateDefault(new JsonSerializerSettings { ContractResolver = resolver }).Deserialize(reader, objectType); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { JsonSerializer.CreateDefault(new JsonSerializerSettings { ContractResolver = resolver }).Serialize(writer, value); }}
并像这样使用它:
[TypeConverter(typeof(FooConverter))][JsonConverter(typeof(NoTypeConverterJsonConverter<Foo>))]public class Foo{ public bool a { get; set; } public bool b { get; set; } public bool c { get; set; } public Foo() { }}public class FooConverter : TypeConverter{ public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType) { if (sourceType == typeof(string)) { return true; } return base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value is string) { string s = value.ToString(); //s = s.Replace("\", ""); Foo f = JsonConvert.DeserializeObject<Foo>(s); return f; } return base.ConvertFrom(context, culture, value); }}
小提琴的例子。
最后,您可能还应该
ConvertTo在类型转换器中实现该方法,请参见如何:实现类型转换器。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)