使用 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
有两点我想指出,然后..
- 您使用的 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 请求主体是计算机的工作,因为它是重复并始终遵循相同的模式
- 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# 命名约定(或允许您重命名以适合您)..
..它们开箱即用,可以解决您现在遇到的这个问题
希望有人能帮助我。这是我用来通过 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
有两点我想指出,然后..
- 您使用的 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 请求主体是计算机的工作,因为它是重复并始终遵循相同的模式
- 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# 命名约定(或允许您重命名以适合您)..
..它们开箱即用,可以解决您现在遇到的这个问题