使用 newtonsoft 反序列化对象时出现问题

problem deserializing object using newtonsoft

希望有人能帮助我。这是我用来通过 api(在本例中为 Twinkly 灯串)检索有关特定设备的一堆数据的代码。 这是我的代码,部分功能正常。

            HttpResponseMessage result = await httpClient.GetAsync(uri);
        string response = await result.Content.ReadAsStringAsync();
        JObject jObject = JObject.Parse(response);
        Layout layout = new Layout();
        layout = JsonConvert.DeserializeObject<Layout>(response);

我说它是“部分”起作用的,因为根级别中的每个 属性 都可以很好地反序列化到模型中,但是 json 也 returns 一个 属性 称为“坐标”,它由每个灯泡的数组条目组成,每个条目具有 x、y、z 的三个值。
我已经尝试了很多东西来从坐标数组中获取数据,并且我可以中断模式查看数据在那里。

但是它没有正确反序列化。我在坐标数组中有正确数量的元素,但它们都是 x:0、y:0、z:0

这是我的模型架构。我希望有人可以帮助我。这是我第一次涉足 api 工作,也是我第一次拥有这样的嵌套模型。

 internal class Layout
{ 
    public int aspectXY { get; set; }
    public int aspectXZ { get; set; }
    public LedPosition[] coordinates { get; set; } 
    public string source { get; set; } //linear, 2d, 3d
    public bool synthesized { get; set; }
    public string uuid { get; set; }
}

internal class LedPosition
{
    double x { get; set; }    
    double y { get; set; }
    double z { get; set; }
}

注意:我试过像这样手动分配属性:

JToken dataToken = jObject.GetValue("coordinates");

确实收到了数据,但它对我没有帮助,因为它只是移动了问题。

我最近从工作中的大狗 CTO 那里学到的一件事是,您实际上可以复制您期望的 JSON,然后转到“编辑”->“选择性粘贴”->“粘贴”JSON as 类 in Visual Studio 并将其粘贴为您需要的 类,并带有适当的 names/properties。真的很光滑。也许试试看它是否会出现与您现在拥有的不同的模型。

你不需要同时解析和反序列化,这就足够了

 var response = await result.Content.ReadAsStringAsync();
 var layout = JsonConvert.DeserializeObject<Layout>(response);

使 LedPosition 属性可见也使它们 public

public class LedPosition
{
   public  double x { get; set; }    
   public double y { get; set; }
   public double z { get; set; }
}

因为它被另一个人使用 class 这个 class 也应该是 public

public class Layout

This is my first foray into api work

有两点我想指出,然后..

  1. 您使用的 api 是否发布了 swagger/open api 文档?
    • 否 - 请参阅下面的 2
    • 是的 - 查看 NSwag(Studio)、Autorest 等工具。您将 swagger.json 提供给它们,它们会生成几千行代码来创建一个客户端,该客户端执行所有 http 调用、反序列化、数据的 类 等。如果这意味着您的代码将结束看起来像:
    var client = new TwinklyLightClient();
    var spec = client.GetTwinklyLightSpec();
    foreach(var coord in spec.Coords)
      Console.Write(spec.X);

这就是 API 应该的样子;创建它们的工具按规则运行,描述它们的工具按规则运行,因此可以通过按规则运行的工具来使用它们 - 编写样板 json 和 http 请求主体是计算机的工作,因为它是重复并始终遵循相同的模式

  1. API 没有发布我们可以用来让计算机为我们编写无聊代码的规范。杜恩。好吧,您可以自己制作规范(不是那么难),也可以稍微手动一些
    • 带上你的json(原始查看并复制)
    • 访问许多将 json 转换为代码的网站中的任何一个 - 我喜欢 http://QuickType.io 因为它支持多种语言,有很多自定义功能并提供自定义的高级示例输入 deser,但还有其他的 - 并将 json 粘贴到
    • 立即将其转换为例如 C# 并可以粘贴到您的项目中
    • 它给出了一个如何在评论中使用它的例子 - 像这样的一行:
    var json = httpCallHereTo.GetTheResponseAsJsonString();
    var twinklyLightSpec = TwinklyLightSpec.FromJson(json);

是的,visual studio 可以从 json 制作 类,但它不是很复杂 - 它完成了工作,但是这些将 json 制作成 c# 的网站进一步允许您选择数组或列表,根对象被称为什么,用指定 json 名称的 JsonProperty 属性装饰每个 属性 并保持 c# 属性 到 c# 命名约定(或允许您重命名以适合您)..

..它们开箱即用,可以解决您现在遇到的这个问题