使用JSON.NET使用注释将嵌套的JSON结构反序列化为扁平类

本文关键字:JSON 反序列化 结构 嵌套 NET 注释 使用 | 更新日期: 2023-09-27 18:00:06

是否可以使用JsonProperty注释将嵌套的Json属性映射到非嵌套的.NET成员?假设你有这样的Json:

{
     "id":9999,
     "created_date":"Thu, 23 Jun 2011 12:56:24 +0000",
     "pos":{
        "type":"someType",
        "coordinates":[
           59.323,
           18.0654
        ]
     }
}

并希望使用将其反序列化为扁平类MyClass

JsonConvert.DeserializeObject<MyClass>(jsonstr);

注释可以用于将Json坐标列表映射到以下类中的Lat和Lng吗:

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

只是好奇。我总是可以这样定义类,它似乎很好用:

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

使用JSON.NET使用注释将嵌套的JSON结构反序列化为扁平类

根据个人经验,在尝试重新使用我的实体进行通信(JSON、XML等)之前,我很挣扎,但在仔细关注现有模式后,我发现除了现有的内部/存储实体之外,还拥有"数据传输对象"将解放我的通信模型,我支付的唯一成本是接受手动操作,但直接地,在两者之间手动编码转换的努力。

如果你宁愿坚持现有的,并且性能没什么大不了的,那么.NET反射就是你的朋友。

我认为最好不要把它压平。不这样做的原因有很多:

  1. 若在某些情况下,您将不得不使用相同名称的字段
  2. 如果要更改属性,则必须重新构造JSON对象从零开始

对您来说,最好的选择是在这里阅读一些关于使用JSon进行数据爬网的内容。非常简单和有用。

之后——如果你仍然坚持的话,你可以把它包在一个漂亮的新课里。

对于非常复杂的JSON情况,我非常喜欢Demis Bellot在ServiceStack.Text中采用的手动映射方法。这允许我将httpResponse.Content传递给JsonConverter.Convert(字符串JSON)方法。

这还有一个额外的好处,那就是保持模型对象的整洁。

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

你可以在这里看到完整的测试。