Deserializing nested JSON structure to a flattened class with Json.NET using annotations

拈花ヽ惹草 提交于 2020-01-10 02:20:07

问题


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; }
}

回答1:


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.




回答2:


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.




回答3:


I Think it's better if you won't flatten it at all. There are multiple reasons why NOT to do so:

  1. if in some point you'll have to fields with same name.
  2. 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.



来源:https://stackoverflow.com/questions/6462148/deserializing-nested-json-structure-to-a-flattened-class-with-json-net-using-ann

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!