Newtonsoft.JSON无法使用TypeConverter属性转换模型

Newtonsoft.JSON无法使用TypeConverter属性转换模型,第1张

Newtonsoft.JSON无法使用TypeConverter属性转换模型

这里发生了一些事情。首先,一个初步的问题:即使没有

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格式以与此匹配,您的反序列化仍将失败,因为
TypeConverter
and和Json.NET尝试递归调用彼此。

因此,您需要做的是全局禁用

TypeConverter
Json.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
在类型转换器中实现该方法,请参见如何:实现类型转换器。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5044992.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-15
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存