So my json data is coming as string like following:
{ "name":"aaa", "sub": "{"x":"sss", "y":"eee"}" }
Sub field is a raw json string here.
My model is like following.
class Main
{
public string Name { get;set;}
public Sub Sub { get;set;}
}
class Sub
{
public string X { get;set;}
public string Y { get;set;}
}
I want to deserialize it like following:
var response = Encoding.UTF8.GetString(bytes); // getting data.
var jsonString = JsonConvert.Deseialize(response).ToString(); // to string.
var model = JsonConvert.Deserialize<Main>(jsonString); // error
The last step throws exception, like "string can not cast to Main" class.
CodePudding user response:
It sounds like you need a 2-step deserialization. If the value of sub
is a string then it's a string, not a Sub
instance. That string may be a JSON representation of a Sub
instance, but that's another deserialization altogether.
First deserialize into the type represented by the whole object:
class Main
{
public string Name { get;set; }
public string Sub { get;set; }
}
and:
var mainObj = JsonConvert.DeserializeObject<Main>(response);
Then mainObj.Sub
would contain the JSON string for your next type:
class Sub
{
public string X { get;set; }
public string Y { get;set; }
}
Which you can deserialize the same way:
var subObj = JsonConvert.DeserializeObject<Sub>(mainObj.Sub);
Overall the process of deserializing a JSON string to an object is the same. You just have to do it twice when you have two JSON strings.
CodePudding user response:
Assuming your question has a typo and you meant to escape the double quotes, e.g.:
{ "name":"aaa", "sub": "{\"x\":\"sss\", \"y\":\"eee\"}" }
Then you can achieve this with a custom converter. For example:
public class NestedJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType,
object? existingValue, JsonSerializer serializer)
{
// Get the raw string
var s = serializer.Deserialize<string>(reader);
// Deserialise into the correct type
return JsonConvert.DeserializeObject(s, objectType);
}
public override void WriteJson(JsonWriter writer, object? value,
JsonSerializer serializer)
=> throw new NotImplementedException();
}
And change your model to add the attribute:
class Main
{
public string Name { get; set; }
[JsonConverter(typeof(NestedJsonConverter))]
public Sub Sub { get; set; }
}
Now you can simply deserialise like this:
var result = JsonConvert.DeserializeObject<Main>(jsonString);