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.
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论