我正在尝试使用接口为 Json.NET 反序列化创建一个抽象层。为了实现这一点,我使用自定义JsonConverter
,它工作得很好,直到引入接口。抛出以下异常:
未处理的异常:Newtonsoft.Json.JsonSerializationException:在“BatchList”上将值设置为“Items”时出错。---> System.InvalidCastException:无法将“System.Collections.Generic.List1[BatchItems]”类型的对象转换为“System.Collections.Generic.List`1[IBatchItems]”
这是在控制台应用程序中重现的设置:
class Program
{
static void Main(string[] args)
{
var jsonBatch = @"{'items': [{'Id': 'name1','info': {'age': '20'}},{'Id': 'name2','info': {'age': '21'}}]}";
DeserializeAndPost(jsonBatch);
}
public static void DeserializeAndPost(string json)
{
IBatchList req;
req = JsonConvert.DeserializeObject<BatchList>(json);
Post(req);
}
public static void Post(IBatchList batchList)
{
Console.WriteLine(batchList.Items.FirstOrDefault().Id);
}
}
public interface IBatchList
{
List<IBatchItems> Items { get; set; }
}
public interface IBatchItems
{
string Id { get; set; }
JObject Info { get; set; }
}
[JsonObject(MemberSerialization.OptIn)]
public class BatchList : IBatchList
{
[JsonProperty(PropertyName = "Items", Required = Required.Always)]
[JsonConverter(typeof(SingleOrArrayConverter<BatchItems>))]
public List<IBatchItems> Items { get; set; }
}
[JsonObject]
public class BatchItems : IBatchItems
{
[JsonProperty(PropertyName = "Id", Required = Required.Always)]
public string Id { get; set; }
[JsonProperty(PropertyName = "Info", Required = Required.Always)]
public JObject Info { get; set; }
}
// JsonConverter
public class SingleOrArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<T>>();
}
return new List<T> { token.ToObject<T>() };
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
List<T> list = (List<T>)value;
if (list.Count == 1)
{
value = list[0];
}
serializer.Serialize(writer, value);
}
public override bool CanWrite
{
get { return true; }
}
}
我希望输出是反序列化的 JSON,因为我提供了用于反序列化的接口的类型:
[JsonConverter(typeof(SingleOrArrayConverter<BatchItems>))]
要使用的。相反,unhandled cast exception
正在被抛出。
请注意,如果我改用SingleOrArrayConverter<IBatchItems>
,我会得到一个异常
Newtonsoft.Json.JsonSerializationException: Could not create an instance of type
因为[JsonConverter(typeof(SingleOrArrayConverter<BatchItems>))]
它旨在为以下接口提供具体类型:public List<IBatchItems> Items { get; set; }
.