如何用 Newtonsoft.Json 正确解析属性为“接口集合<接口>”的JSON字符串

changechange 2015-04-14 04:59:06
如何用 Newtonsoft.Json 正确解析属性为“接口集合<接口>”的字符串
我想要能够正确解析 CC 类,也就是其属性是 IList<I> ,都是接口类型的。
请注意,DD 类中可能还继续包含更深层次的集合接口。比如 DD还包含 D3 是 IList<IDD4> .

//CC occ = JsonConvert.DeserializeObject<CC>(s); //提示错误: Error setting value to 'C3' on 'ConsoleApplication1.CC'.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Converters;
using System.Diagnostics;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{

string s = "{\"B\":\"sdfasdf\",\"C3\":[{\"a\":\"sdfasdf\"},{\"a\":\"adsfasdf33333333\"}]}";
//提问,如何用 Newtonsoft.Json 正确解析属性为“接口集合<接口>”的字符串
//我想要能够正确解析 CC 类,也就是其属性是 IList<I> ,都是接口类型的。
//请注意,DD 类中可能还继续包含更深层次的集合接口。比如 DD还包含 D3 是 IList<IDD4> .

//CC occ = JsonConvert.DeserializeObject<CC>(s); //提示错误: Error setting value to 'C3' on 'ConsoleApplication1.CC'.

CC2 occ2 = JsonConvert.DeserializeObject<CC2>(s); //能够正确解析
Debug.Print(((DD)occ2.C3[0]).a);

//CC3 occ3 = JsonConvert.DeserializeObject<CC3>(s); //提示错误: Error setting value to 'C3' on 'ConsoleApplication1.CC'.
//Debug.Print(((DD)occ3.C3[0]).a);


}
}


/// <summary>
/// 请注意 CC CC2 CC3 只是在 C3 的定义上有区别。 CC 是我要最终实现的类。
/// </summary>
public class CC2
{
public string B;
[JsonConverter(typeof(ConcreteTypeConverter<List<DD>>))]
public IList<DD> C3;
}


public class CC3
{
public string B;
[JsonConverter(typeof(ConcreteTypeConverter<List<DD>>))]
public List<IDD> C3;
}

public class CC
{
public string B;
[JsonConverter(typeof(ConcreteTypeConverter<List<DD>>))]
public IList<IDD> C3;
}
public interface IDD
{
string a { get; set; }
}
public class DD : IDD
{
public string a { get; set; }
}

public class ConcreteTypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
//assume we can convert to anything for now
return true;
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//explicitly specify the concrete type we want to create
return serializer.Deserialize<T>(reader); //实现不了
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//use the default serialization - it works fine
serializer.Serialize(writer, value);
}
}
}
...全文
320 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_28840645 2016-03-09
  • 打赏
  • 举报
回复
版 主,这个问题你还解决了?
changechange 2015-04-14
  • 打赏
  • 举报
回复
不要扯其他的了,还是专注于问题吧
changechange 2015-04-14
  • 打赏
  • 举报
回复
你应该先看设计意图,设计的目的就是可以随意替换c3,当然不能有继承关系
  • 打赏
  • 举报
回复
List<DD> 跟 List<IDD> 毫无关系,没有继承关系。 你应该先学号泛型,再重新设计你的程序意图。
changechange 2015-04-14
  • 打赏
  • 举报
回复
不要用问题来回答问题。 只要属性符合,完全没问题,而且我也手动给出了反序列化的类型。 两个类,属性一样,方法一样,所有对外公开的接口都一样,就封装性来说他就是同一个类,至少是可以随意替换的一类。所以我只要完成这个就可以了。
Rajesh_James 2015-04-14
  • 打赏
  • 举报
回复
已知:

interface IPet
{
      string name;
}

class Cat:IPet
{
       public string name{get;set;}
}

class Dog:IPet
{
       public string name{get;set;}
}
现有Json: {name:"Kitty"} 被 IPet来反序列化,你能确定它是Cat还是Dog吗?
  • 打赏
  • 举报
回复
高端大气上档次,低调奢华有内涵

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧