简体   繁体   中英

Is it possible to deserialize into property rather than an object

Appologies if its already been asked, I could not find anything helpful to my situation.

I need to deserialize a JSON in a property of my object instead of a whole object. The reason I am trying to do it, is that is simply generics.

I have the following situation

For instance I have

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(){ }
}

My Json is:

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

Is it possible to deserialize(+ generics) my JSON directly into my Wanted class instead of serializing into A and then assign it into Wanted ?

The goal is after the serialization I will have object with type Wanted and an array with 2 users in it.

Since the JSON does not match the class you want to deserialize into, and you cannot change the JSON, you will need to use a custom JsonConverter to bridge the gap.

To make it work you'll need to introduce an interface IHasUsers which your Wanted class (or its base class) will need to implement:

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

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

Then you can make a generic converter which will instantiate the Wanted class (or any other class which implements IHasUsers ) and populate the Users property:

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();
    }
}

Then you can deserialize your JSON like this:

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

Here is a demo: https://dotnetfiddle.net/KL6Ok6

Hope this is what you were looking for.

Since Wanted is "your desired class", there needs to be an instance of Wanted created somewhere. You might just as well create it yourself rather than having a derserializer do it for you. Once you have done this you can simply set the Users property to the deserialized data:

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

You don't deserialize some data "into a property" without deserializing it to some object of some type first. Once you have done this you can then set the property to the object that contains the deserialized data.

There is nothing generic about Wanted here though and the deserializer cannot be supposed to figure out that it should create a Wanted or any other type unless you specify the type to derserialize the data to somewhere.

And there is no point of deserializing the data to a type defined at compile time if you don't know that the data matches this type. Then you might as well create an anonymous object or a dictionary of key/value pairs.

You can use Newtonsoft.json . Try below

 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
      }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM