Deserializing nested JSON structure to a flattened class with Json.NET using annotations
Is it possible to use JsonProperty annotation to map a nested Json property to a non-nested .NET member? Say you've got some Json like this:
{
"id":9999,
"created_date":"Thu, 23 Jun 2011 12:56:24 +0000",
"pos":{
"type":"someType",
"coordinates":[
59.323,
18.0654
]
}
}
and want to deserialize it into a flattened class MyClass using
JsonConvert.DeserializeObject<MyClass>开发者_开发知识库(jsonstr);
Can annotations be used to map the Json coordinates list to Lat and Lng in the class below:
public class MyClass {
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("created_date")]
public DateTime Created { get; set; }
[JsonProperty("????")]
public float Lat { get; set; }
[JsonProperty("?????")]
public float Lng { get; set; }
}
Just curious. I can always define the class like this and it seems to work fine:
public class MyClass {
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("date_created")]
public DateTime Created { get; set; }
[JsonProperty("pos")]
public PosClass Pos { get; set; }
}
public class PosClass
{
public List<float> coordinates { get; set; }
}
From personal experience, I struggled before trying to re-use my entities for communication (JSON, XML ... etc.) but after paying closer attention to existing patterns, I found out that having "data transfer objects" in addition to internal / storage entities that you already have will liberate my communication models and the only cost I paid was to accept doing manual, yet straight-forward, effort of manually-coded conversion between the two.
If you'd rather stick to what you have and performance is no big deal, then .NET reflection is your friend.
I Think it's better if you won't flatten it at all. There are multiple reasons why NOT to do so:
- if in some point you'll have to fields with same name.
- if you'd like to change an attribute, you'll have to reconstruct the JSON object from scratch.
The best option for you is to read a bit about data crawling using JSon - here. Very easy and useful.
After - if you'll still insist, you can wrap it in a nice new class.
For really complex JSON Situations I really like the manual mapping approach Demis Bellot has taken with ServiceStack.Text. This allows me to pass an httpResponse.Content to a JsonConverter.Convert(string json) method.
This has the added benefit of keeping your model objects squeaky clean.
var place = JsonObject.Parse(JsonCentroid)
.Object("place")
.ConvertTo(x => new Place
{
WoeId = x.Get<int>("woeid"),
PlaceTypeName = x.Get(""),
PlaceTypeNameAttrs = x.Object("placeTypeName attrs"),
Name = x.Get("Name"),
BoundingBox = x.Object("boundingBox")
.ConvertTo(y => new BoundingBox
{
SouthWest = y.Object("southWest").ConvertTo(toCentroid),
NorthEast = y.Object("northEast").ConvertTo(toCentroid)
}),
});
You can see the full test here.
精彩评论