【问题标题】:Deserializing nested JSON structure to a flattened class with Json.NET using annotations使用注释将嵌套的 JSON 结构反序列化为使用 Json.NET 的扁平类
【发布时间】:2011-09-21 16:09:23
【问题描述】:

是否可以使用 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 表示的建模。

标签: c# asp.net json json.net


【解决方案1】:

对于非常复杂的 JSON 情况,我非常喜欢 Demis Bellot 使用 ServiceStack.Text 采用的手动映射方法。这允许我将 httpResponse.Content 传递给 JsonConverter.Convert(string 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)
            }),
});

你可以看到完整的测试here

【讨论】:

    【解决方案2】:

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

    1. 如果在某些时候您必须使用相同名称的字段。
    2. 如果你想改变一个属性,你必须重建 JSON 对象 从头开始。

    对你来说最好的选择是阅读一些关于使用 JSon 进行数据爬取的知识 - here。 非常简单实用。

    之后 - 如果你仍然坚持,你可以将它包装在一个不错的新类中。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • DTO 万岁。此外,如果您使用 Automapper 之类的工具,则不必对所有转换进行硬编码。
      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 2013-12-19
      • 2021-11-19
      • 2017-09-18
      • 1970-01-01
      相关资源
      最近更新 更多