-1

My JSON string is like this:

{ 
    "number": "1", 
    "optionsList": [ 
        "{\"answer\":\"42\", \"options\":\"washington\"}", 
        "{\"answer\":\"65\", \"options\":\"new england\"}" 
    ] 
}

I understand the optionsList JSON is malformed and not correct JSON but I cannot change this and would like to handle this in my code. Such that it can be deserialized correctly into a c# class.

I did:

Root.cs


public class Root { 
    public Root() {
        Number = new Number(); 
        OptionsList = new List<OptionsList>();
    }

    [JsonProperty(PropertyName = "number")]
        public string Number { get; internal set; }

    [JsonProperty(PropertyName = "optionsList")]
        public List<OptionsList> OptionsList { get; internal set; }
} 

OptionsList.cs


public class OptionsList { 
    [JsonProperty(PropertyName = "answer")] 
        public string Answer { get; internal set; }

    [JsonProperty(PropertyName = "options")]
        public string Options { get; internal set; }
} 

Deserializing like this: deserializedResponse = JsonConvert.DeserializeObject<T>(response); //response is the JSON Object

By simply doing this, I am getting an exception.

Exception trace:

 ---> Newtonsoft.Json.JsonSerializationException: Error converting value "{"answer":"42","options":"washington"}" to type 'Types.OptionsList'. Path 'OptionsList[0]', line 1, position 1947.
 ---> System.ArgumentException: Could not cast or convert from System.String to Types.OptionsList.
   at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
   at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)

How can I deserialize optionsList into a c# class correctly?

Maybe if I can deserialize each string of optionsList individually before this, it would work but I don't know where to do this. Or can I add something in the constructor of OptionsList or the Root class itself to do this?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Jorge
  • 1
  • 1
  • 2
    _"I understand the optionsList JSON is malformed "_ not malformed, just JSON encoded values. They will need parsing separately. – phuzi Feb 20 '23 at 12:45
  • Does this answer your question? [How do I convert an escaped JSON string within a JSON object?](https://stackoverflow.com/questions/39154043/how-do-i-convert-an-escaped-json-string-within-a-json-object) – Yong Shun Feb 21 '23 at 00:36

1 Answers1

1

you have an array of json strings inside of a json string. So you have to deserialize the nesteded json strings at first

    var jObj = JObject.Parse(json);

    jObj["optionsList"] = new JArray(jObj["optionsList"]
                                    .Select(x => JObject.Parse((string)x)));

    Root data = jObj.ToObject<Root>();
Serge
  • 40,935
  • 4
  • 18
  • 45