是否可以反序列化为属性而不是对象

时间:2018-06-29 13:52:22

标签: c# .net json json.net

如果已提出要求,我找不到对我的情况有用的任何信息。

我需要在我的对象的属性(而不是整个对象)中反序列化JSON。我尝试这样做的原因是,这只是泛型。

我有以下情况

例如我有

Class User 
{
   int UserId {get;set;}
   string Name {get;set;
}

Class Wanted : CustomClass
{
   User[] Users {get;set;}

   public override void Map(){ } 
   public override void Scan(){ }
}

我的杰森是:

[
  {
    "userId": 1,
    "name": "Josh"
  },
  {
    "userId": 5,
    "name" : "Martin"
  }
]

是否可以将JSON直接反序列化(+泛型)到我的Wanted类中,而不是序列化为A然后再将其分配给Wanted中?

目标是序列化后,我将拥有类型为Wanted的对象以及其中包含2个用户的数组。

3 个答案:

答案 0 :(得分:2)

由于JSON与您要反序列化的类不匹配,并且您无法更改JSON,因此需要使用自定义JsonConverter来弥合差距。

要使其正常工作,您需要引入一个接口IHasUsers,您的Wanted类(或其基类)将需要实现:

interface IHasUsers
{
    User[] Users { get; set; }
}

class Wanted : CustomClass, IHasUsers
{
    public User[] Users { get; set; }
    ...
}

然后,您可以创建一个通用转换器,该转换器将实例化Wanted类(或实现IHasUsers的任何其他类)并填充Users属性:

class UserListConverter<T> : JsonConverter where T: IHasUsers, new()
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(IHasUsers).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray array = JArray.Load(reader);
        T obj = new T() { Users = array.ToObject<User[]>() };
        return obj;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后您可以像这样反序列化JSON:

Wanted wanted = JsonConvert.DeserializeObject<Wanted>(json, new UserListConverter<Wanted>());

这是一个演示:https://dotnetfiddle.net/KL6Ok6

希望这就是您想要的。

答案 1 :(得分:1)

由于Wanted是“您所需的类”,因此需要在某处创建Wanted的实例。您也可以自己创建它,而不是使用解串器为您完成。完成此操作后,您可以简单地将Users属性设置为反序列化数据:

var wanted = new Wanted() { Users = JsonConvert.DeSerialize<User[]>(myString) };

您不会先将某些数据反序列化为“属性”,而不必先将其反序列化为某种类型的对象。完成此操作后,您可以将属性设置为包含反序列化数据的对象。

尽管这里Wanted并没有通用的含义,并且除非您指定将数据反序列化到某个地方的类型,否则反序列化器不能假定它应该创建Wanted或任何其他类型。

如果您不知道数据与该类型匹配,则没有必要将数据反序列化为在编译时定义的类型。然后,您最好创建一个匿名对象或键/值对字典。

答案 2 :(得分:0)

您可以使用Newtonsoft.json。请尝试以下

 var files = JArray.Parse(YourJSON);
 var recList = files.SelectTokens("$").ToList();
 foreach (JObject item in recList.Children())
  {
    foreach (JProperty prop in item.Children())
      {
         string key = prop.Name.ToString();
         string value = prop.Value.ToString();
        // and add these to an array
      }
  }