c# – 反序列化子类中的匿名顶级数组
我有一个
JSON响应,包含在外部数组中,如下所示:
[ { "type": "a" },{ "type": "b","id": 1 },{ "type": "c","name": "somename" } ] 我试图将此转换为对象,如下所示: class LoginOptions { public IList<ILoginOption> Options { get; set; } } interface ILoginOption { [JsonProperty("type")] LoginType LoginType { get; } } class LoginOptionA : ILoginOption{ public LoginType LoginType { get { return LoginType.A; } } } class LoginOptionB : ILoginOption{ public LoginType LoginType { get { return LoginType.B; } } [JsonProperty("id")] public int Id { get; set; } } class LoginOptionC : ILoginOption{ public LoginType LoginType { get { return LoginType.C; } } [JsonProperty("name")] public string Name { get; set; } } 导致此异常的原因是:
我宁愿不在我的LoginOptions类中实现一个集合,因为当我应该能够将它存储在字段中时,这将是太多的开销.使用[JsonArray]属性返回无法创建和填充列表类型Library.Models.Domain.LoginOptions. 我发现的大多数资源都处理顶部数组的{“name”:“value”}对,而不是匿名数组.我该如何反序化呢? 我相应地改变了我的代码: public sealed class LoginOptions { [JsonConverter(typeof(LoginOptionConverter))] public IList<ILoginOption> Options { get; set; } } 我的呼叫调度程序解析JSON的地方: private List<ILoginOption> DeserializeObject<List<ILoginOption>>(Stream stream) { using (StreamReader sr = new StreamReader(stream)) using (JsonReader reader = new JsonTextReader(sr)) { return new JsonSerializer().Deserialize<List<ILoginOption>>(reader); } } 和这样的自定义转换器: internal class LoginOptionConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(ILoginOption); } public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer) { var item = JObject.Load(reader); var data = item["type"].Value<string>(); if (data == "UsernamePassword") { return item.ToObject<LoginOptionA>(); } if (data == "Saml") { return item.ToObject<LoginOptionB>(); } if (data == "Crm") { return item.ToObject<LoginOptionC>(); } throw new ArgumentException("Invalid JSON response"); } } 这会引发错误
运用 new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }; 建议here没有什么区别. 请注意,在将其放入自定义转换器之前会抛出此错误:创建JsonSerializer时会抛出此错误. 实例化发生在这里: var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects }; using (StreamReader sr = new StreamReader(stream)) using (JsonReader reader = new JsonTextReader(sr)) { return JsonSerializer.Create(settings).Deserialize<List<ILoginOption>>(reader); } 解决方法
由于JSON中的顶级是一个数组,因此您应该直接反序列化为一个列表.不需要包装类来保存列表.
List<ILoginOption> loginOptions = JsonConvert.DeserializeObject<List<ILoginOption>>(json); 现在,因为你的列表将包含几种不同类型的ILoginObjects,Json.Net将不知道要创建哪些,因为它反序列化列表.为此你需要一个JsonConverter. This answer显示了如何创建转换器来处理这个问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |