0

I have a situation where I have Json Values as List of string.

List<string> values = new List<string>()
{
    "{\"Id\":\"SC\",\"Value\":8563}",
    "{\"Id\":\"SC\",\"Value\":8563}",
    "{\"Id\":\"SC\",\"Value\":8563}"
};

How to I de-serialize into a List of Objects:

public class ClassA
{
   public string Id {get; set;}
   public int Value {get;set;}
}

var objectValues = JsonConvert.DeserializeObject<IEnumerable<ClassA>>(values);

I couldn't deserialize when I am passing values list and it is expecting a string as parameter; can I create an extension method or is there an easier way to deserizalize ?

halfer
  • 19,824
  • 17
  • 99
  • 186
VR1256
  • 1,266
  • 4
  • 28
  • 56
  • Why are you storing each object in a string array? Why not keep the original JSON array structure? If you are unable to do that, then you need to iterate over the `values` list and deserialize _each individual item_. – maccettura Mar 02 '20 at 19:09
  • Also the act of "deserializing" JSON means taking a `string` and turning it into a concrete object. I am not sure why you thought you could deserialize something that is already an object – maccettura Mar 02 '20 at 19:10
  • Actually now that I think of it, what does extension methods have to do with anything here? – maccettura Mar 02 '20 at 19:13
  • @maccettura I have the Json value rows in the backend table, I read them from the table as a collection of Object and I need to deserialize the collection of Json into a collection of ClassA object. – VR1256 Mar 02 '20 at 19:44

3 Answers3

2

Try this:

            List<ClassA> deserialized = new List<ClassA>();
            List<string> values = new List<string>()
            {   
                "{\"Id\":\"SC\",\"Value\":8563}",
                "{\"Id\":\"SC\",\"Value\":8563}",
                "{\"Id\":\"SC\",\"Value\":8563}"
            };
            foreach (var item in values)
            {
                var objectValue = JsonConvert.DeserializeObject<ClassA>(item);
                deserialized.Add(objectValue);
            }

And as extension:

 public static List<ClassA> ToClassA(this List<string> stringList)
    {
        List<ClassA> deserialized = new List<ClassA>();
        foreach (var item in stringList)
        {
            var objectValue = JsonConvert.DeserializeObject<ClassA>(item);
            deserialized.Add(objectValue);
        }
        return deserialized;
    }

Generic extension

public static List<T> ToList<T>(this List<string> stringList) where T : class
        {
            List<T> deserialized = new List<T>();
            foreach (var item in stringList)
            {
                var objectValue = JsonConvert.DeserializeObject<T>(item);
                deserialized.Add(objectValue);
            }
            return deserialized;
        }

use:

var result = values.ToList<ClassA>();
svladimirrc
  • 216
  • 1
  • 6
  • maccettura an exaple of use case. – svladimirrc Mar 02 '20 at 19:32
  • Yes you have used extension methods to solve this, but my point was that "extension methods" are an implementation detail. Its not required to solve the issue. – maccettura Mar 02 '20 at 19:47
  • 1
    @svladimirrc thank you very much, I have different type of Json values in a table and by each type I have to get a set of related Json values into a collection and then deserialize it to convert to a List of object of that class type to do some operations, and that is why to keep it generic I might need an extension method and your answer helped me. I don't know why question was downvoted :) – VR1256 Mar 02 '20 at 20:01
2

You can convert the values list to string of Array by building a new Json, like the following code:

var objectValues = JsonConvert.DeserializeObject<IEnumerable<ClassA>>($"[{string.Join(",", values)}]");

I hope that will help you out.

Mohammed Sajid
  • 4,778
  • 2
  • 15
  • 20
0
public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder,
    string columnType = null, string columnName = "", JsonSerializerSettings settings = null)
{
    var converter = new ValueConverter<T, string>(
        v => JsonConvert.SerializeObject(v, settings),
        v => JsonConvert.DeserializeObject<T>(v, settings));

    var comparer = new ValueComparer<T>(
        (l, r) => JsonConvert.SerializeObject(l, settings) == JsonConvert.SerializeObject(r, settings),
        v => v == null ? 0 : JsonConvert.SerializeObject(v, settings).GetHashCode(),
        v => JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(v, settings), settings));

    propertyBuilder.HasConversion(converter);
    if (columnType != null) propertyBuilder.HasColumnType(columnType);

    if (columnName == "")
        propertyBuilder.HasColumnName($"Json_{propertyBuilder.Metadata.Name}");
    else if (columnName != null)
        propertyBuilder.HasColumnName(columnName);

    propertyBuilder.Metadata.SetValueConverter(converter);
    propertyBuilder.Metadata.SetValueComparer(comparer);

    return propertyBuilder;
}
  • It seems a little much. What does it add above the accepted answer? – Valerij Dobler May 28 '22 at 19:51
  • Kindly add more details to your answer, explanations on how your code works and how this address the OP's question would be a great help not just for the asker but also for the future researchers. – Kuro Neko May 30 '22 at 08:49