SYL*_*SYL 1 c# json.net deserialization
鉴于这些类定义:
public class TypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => serializer.Serialize(writer, value);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => serializer.Deserialize<T>(reader);
}
public interface ISubStuff
{
string Item { get; set; }
}
public class SubStuff : ISubStuff
{
public string Item { get; set; }
}
public interface IMainStuff
{
Dictionary<string, ISubStuff> SubStuff { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我尝试在方法声明中使用 TypeConverter 类进行反序列化,如下所示,但它不起作用:
public class MainStuff : IMainStuff
{
[JsonConverter(typeof(TypeConverter<Dictionary<string, SubStuff>>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
下面对 json 进行反序列化的调用会导致unable to cast object of type Dictionary<string, SubStuff> to Dictionary<string, ISubStuff>异常。
var jsonText = "{ \"SubStuff\": { } }";
var deser = JsonConvert.DeserializeObject<MainStuff><jsonText);
Run Code Online (Sandbox Code Playgroud)
您的问题是 c#Dictionary<TKey, TValue>不是协变的。即,尽管SubStuff 是 ISubStuff,但Dictionary<string, SubStuff> 不是。 Dictionary<string, ISubStuff>因此,当 Json.NET 尝试将 back 设置Dictionary<string, SubStuff>为MainStuff.SubStuff属性时,InvalidCastException会抛出异常。
有关为什么读/写集合不协变的一般解释,请参阅此答案。它对缺乏协变性的讨论List<T>同样适用于通用字典。
您可以做的是将您的onlyJsonProperty.ItemConverterType应用于字典中的值,如下所示:TypeConverter<T>
public class MainStuff : IMainStuff
{
[JsonProperty(ItemConverterType = typeof(TypeConverter<SubStuff>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
public class TypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var msg = string.Format("This converter should be applied directly with [JsonProperty(ItemConverterType = typeof(TypeConverter<{0}>))] or [JsonProperty(typeof(TypeConverter<{0}>))]",
typeof(T));
throw new NotImplementedException(msg);
}
public override bool CanWrite { get { return false; } }
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 serializer.Deserialize<T>(reader);
}
}
Run Code Online (Sandbox Code Playgroud)
小提琴样本。
顺便说一句,JsonConverter您可以继承自:CustomCreationConverter<>而不是继承自:
public class MainStuff : IMainStuff
{
[JsonProperty(ItemConverterType = typeof(TypeConverter<ISubStuff, SubStuff>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
public class TypeConverter<T, TSerialized> : CustomCreationConverter<T>
where TSerialized : T, new()
{
public override T Create(Type objectType)
{
return new TSerialized();
}
}
Run Code Online (Sandbox Code Playgroud)
样本小提琴#2。
最后,作为替代方案,您可以研究该TypeNameHandling设置的使用。
| 归档时间: |
|
| 查看次数: |
1955 次 |
| 最近记录: |