Reputation: 1796
I have the following Json string that I need to deserialize.
{"123456789":
{"short_description":"Delivered",
"detail_description":"Your item has been delivered"
}
}
The first field "123456789" is an id number, so basically this value can be different depending on the data being queried.
I'm using C# in visual studio. Obviously because the value of the first field can change I can't use a predefined class to deserialize the JSON into because this field will be used as the class name but the field value won't match the class name.
Is there a way to deserialize this into some sort of dynamic class but still access the fields as if it was a predefined class?
Alternatively is there a way to deserialize this into a predefined class even thought the class name doesn't match?
The service providing this data is a third party one so i don't have any control over it.
Upvotes: 3
Views: 8796
Reputation: 2361
I liked answer above so I refactored it a bit. You'll need references to System.Web.Extensions.dll
and System.Web.Script.Serialization
.
Here's the class:
public class Order
{
public string OrderNum { private set; get; }
public string ShortDesc { private set; get; }
public string Desc { private set; get; }
public static Order FromJson(string jsonResult)
{
JavaScriptSerializer js = new JavaScriptSerializer();
// Should deserialize right to Dictionary<string, object>
// var result = ((Dictionary<string, object>)js.Deserialize<dynamic>(jsonResult)).First();
var result = js.Deserialize<Dictionary<string, object>>(jsonResult).First();
var detail = (Dictionary<string, object>)result.Value;
return new Order()
{
OrderNum = result.Key,
ShortDesc = detail["short_description"].ToString(),
Desc = detail["detail_description"].ToString()
};
}
}
And how to call it:
string json = "{\"123456789\": {\"short_description\":\"Delivered\", \"detail_description\":\"Your item has been delivered\" } }";
Order o = Order.FromJson(json);
You'll need to implement error handling on your own however.
Upvotes: 3
Reputation: 1708
Here is one way which I use in production code. It might not be perfect, but it gets the job done.
using using System.Web.Script.Serialization;
// .....
public object GetJson(string url)
{
var json = Get(url); // I have code that makes this work, it gets a JSON string
try
{
var deserializer = new JavaScriptSerializer();
var result = deserializer.DeserializeObject(json);
return result;
}
catch (ArgumentException e)
{
// Error handling....
}
}
The object you receive back will be a generic Map, List, or whatever depending on the structure of the JSON. If you know what structure to expect, this is very useful without writing a customized parser or target object type.
You could then enumerate the keys of the Map, for example, to find your key that varies. A wrapper or conversion would then provide a consistent API to the rest of your application layer. Something like:
public class Order {
public string OrderNum { private set; get; }
public string ShortDesc { private set; get; }
public string Desc { private set; get; }
public static Order FromJson(object jsonResult)
{
var m = jsonResult as Map<string, object>;
// Handle errors, but I am not
var firstPair = m.First();
var detail = firstPair.Value as Map<string, object>;
var dummy = new Order()
{
OrderNum = firstPair.Key,
ShortDesc = detail["short_description"].ToString();
Desc = detail["detail_description"].ToString();
}
return dummy;
}
}
Upvotes: 5