在JSON中找不到必需的属性“概率”。(Required property 'probability' not found in JSON. Path)

系统教程 行业动态 更新时间:2024-06-14 17:04:03
在JSON中找不到必需的属性“概率”。(Required property 'probability' not found in JSON. Path)

我正在反序列化到以下类:

public abstract class Tail_Metrics { [DataMember(Order = 1, IsRequired = true)] public double probability { get; set; } [DataMember(Order = 2, IsRequired = true)] public double min { get; set; } [DataMember(Order = 3)] public double max { get; set; } [DataMember(Order = 4, IsRequired = true)] public double mean { get; set; } [DataMember(Order = 5)] public double variance { get; set; } [DataMember(Order = 6)] public double skewness { get; set; } [DataMember(Order = 7)] public double kurtosis { get; set; } } public class Layer_Tail_Metrics : Tail_Metrics { }

如您所见,概率,最小值和平均值是必需的,其余的是可选的。

我从我的服务器反序列化以下JSON响应:

{ "probability": 0.01, "mean": 0, "variance": 0, "min": 0, "max": 0 }

我得到一个Newtonsoft.Json.JsonSerializationException , Required property 'probability' not found in JSON. Path '', line 1, position 95.的消息Required property 'probability' not found in JSON. Path '', line 1, position 95. Required property 'probability' not found in JSON. Path '', line 1, position 95.

怎么可能? 该属性存在于JSON中,并且具有正确的类型!

最奇怪的是,如果我从DataMember属性中删除IsRequired属性,我将停止获取此异常,并且对象完全反序列化。 如果其中任何一个将IsRequired属性设置为true,则该属性将抛出相同的异常。


反序列化代码是:

T retVal = converter.Deserialize<T>(response);

其中typeof(T)是Layer_Tail_Metrics

converter是一个实现RestSharp.Deserializers.IDeserializer的类,如下所示:

using Newtonsoft.Json; public class RestSharp...Converter : RestSharp.Deserializers.IDeserializer { //... private JsonSerializerSettings deserializerSettings; public RestSharpDataContractNewtonsoftJsonConverter() { Culture = CultureInfo.InvariantCulture; ContentType = "application/json"; deserializerSettings = new JsonSerializerSettings() { Converters = new JsonConverter[]{ new Newtonsoft.Json.Converters.IsoDateTimeConverter() } }; } public T Deserialize<T>(IRestResponse response) { return Deserialize<T>(response.Content); } public T Deserialize<T>(String json) { return JsonConvert.DeserializeObject<T>(json, deserializerSettings); } }

这是一个重现错误的小型独立示例:

[DataContract()] public abstract class Tail_Metrics { [DataMember(IsRequired = true)] public double probability { get; set; } public Tail_Metrics(double probability) { this.probability = probability; } } public class Layer_Tail_Metrics : Tail_Metrics { public Layer_Tail_Metrics(double probability) : base(probability) { } } class TestClass { static void Main(string[] args) { string json = @" { ""probability"": 0.01 }"; Layer_Tail_Metrics tm = Newtonsoft.Json.JsonConvert.DeserializeObject<Layer_Tail_Metrics>(json); } }

I am deserializing to the following class:

public abstract class Tail_Metrics { [DataMember(Order = 1, IsRequired = true)] public double probability { get; set; } [DataMember(Order = 2, IsRequired = true)] public double min { get; set; } [DataMember(Order = 3)] public double max { get; set; } [DataMember(Order = 4, IsRequired = true)] public double mean { get; set; } [DataMember(Order = 5)] public double variance { get; set; } [DataMember(Order = 6)] public double skewness { get; set; } [DataMember(Order = 7)] public double kurtosis { get; set; } } public class Layer_Tail_Metrics : Tail_Metrics { }

As you can see, probability, min, and mean are required, the rest are optional.

I am deserializing the following JSON response from my server:

{ "probability": 0.01, "mean": 0, "variance": 0, "min": 0, "max": 0 }

And I am getting a Newtonsoft.Json.JsonSerializationException with the message Required property 'probability' not found in JSON. Path '', line 1, position 95.

How can that be? The property is present in the JSON, and has the correct type!

The weirdest thing is that if I remove the IsRequired property from the DataMember attributes, I stop getting this exception and the object deserializes perfectly. If any of them has the IsRequired property set to true, that property throws the same exception.


Deserialization code is:

T retVal = converter.Deserialize<T>(response);

where typeof(T) is Layer_Tail_Metrics

converter is a class implementing RestSharp.Deserializers.IDeserializer as follows:

using Newtonsoft.Json; public class RestSharp...Converter : RestSharp.Deserializers.IDeserializer { //... private JsonSerializerSettings deserializerSettings; public RestSharpDataContractNewtonsoftJsonConverter() { Culture = CultureInfo.InvariantCulture; ContentType = "application/json"; deserializerSettings = new JsonSerializerSettings() { Converters = new JsonConverter[]{ new Newtonsoft.Json.Converters.IsoDateTimeConverter() } }; } public T Deserialize<T>(IRestResponse response) { return Deserialize<T>(response.Content); } public T Deserialize<T>(String json) { return JsonConvert.DeserializeObject<T>(json, deserializerSettings); } }

Here is a small standalone sample that reproduces the error:

[DataContract()] public abstract class Tail_Metrics { [DataMember(IsRequired = true)] public double probability { get; set; } public Tail_Metrics(double probability) { this.probability = probability; } } public class Layer_Tail_Metrics : Tail_Metrics { public Layer_Tail_Metrics(double probability) : base(probability) { } } class TestClass { static void Main(string[] args) { string json = @" { ""probability"": 0.01 }"; Layer_Tail_Metrics tm = Newtonsoft.Json.JsonConvert.DeserializeObject<Layer_Tail_Metrics>(json); } }

最满意答案

它使用以下控制台程序与JSON.Net v5.0.8(NuGet中的最新版本)对我来说很好用:

class Program { static void Main(string[] args) { string json = @" { ""probability"": 0.01, ""mean"": 0, ""variance"": 0, ""min"": 0, ""max"": 0 }"; var tm = JsonConvert.DeserializeObject<Layer_Tail_Metrics>(json); Console.WriteLine("probability: " + tm.probability); Console.WriteLine("mean: " + tm.mean); Console.WriteLine("variance: " + tm.variance); Console.WriteLine("min: " + tm.min); Console.WriteLine("max: " + tm.max); } [DataContract] public class Layer_Tail_Metrics : Tail_Metrics { } [DataContract] public class Tail_Metrics { [DataMember(Order = 1, IsRequired = true)] public double probability { get; set; } [DataMember(Order = 2, IsRequired = true)] public double min { get; set; } [DataMember(Order = 3)] public double max { get; set; } [DataMember(Order = 4, IsRequired = true)] public double mean { get; set; } [DataMember(Order = 5)] public double variance { get; set; } [DataMember(Order = 6)] public double skewness { get; set; } [DataMember(Order = 7)] public double kurtosis { get; set; } } }

这是输出:

probability: 0.01 mean: 0 variance: 0 min: 0 max: 0

JSON是您发布了从服务器获得的完整JSON响应,还是包装在外部对象中? 如果它被包装在另一个对象中,那么这可以解释问题。 例如,如果您的JSON实际上如下所示:

{ "response": { "probability": 0.01, "mean": 0, "variance": 0, "min": 0, "max": 0 } }

并且您尝试将其反序列化为Tail_Metrics ,然后JSON.Net将无法匹配任何属性,因为它们都是JSON中的一个级别。 如果您在属性上设置了“IsRequired = true”,那么这将导致JSON.Net抛出您看到的异常。 如果你删除它,那么JSON.Net将简单地为你的类中的double属性分配一个默认值零,它在JSON中找不到匹配项。 如果你的所有数据在JSON中恰好都是零,那么即使它真的无声地失败,它看起来也会起作用。

It works fine for me using the following console program with JSON.Net v5.0.8 (the latest in NuGet):

class Program { static void Main(string[] args) { string json = @" { ""probability"": 0.01, ""mean"": 0, ""variance"": 0, ""min"": 0, ""max"": 0 }"; var tm = JsonConvert.DeserializeObject<Layer_Tail_Metrics>(json); Console.WriteLine("probability: " + tm.probability); Console.WriteLine("mean: " + tm.mean); Console.WriteLine("variance: " + tm.variance); Console.WriteLine("min: " + tm.min); Console.WriteLine("max: " + tm.max); } [DataContract] public class Layer_Tail_Metrics : Tail_Metrics { } [DataContract] public class Tail_Metrics { [DataMember(Order = 1, IsRequired = true)] public double probability { get; set; } [DataMember(Order = 2, IsRequired = true)] public double min { get; set; } [DataMember(Order = 3)] public double max { get; set; } [DataMember(Order = 4, IsRequired = true)] public double mean { get; set; } [DataMember(Order = 5)] public double variance { get; set; } [DataMember(Order = 6)] public double skewness { get; set; } [DataMember(Order = 7)] public double kurtosis { get; set; } } }

Here is the output:

probability: 0.01 mean: 0 variance: 0 min: 0 max: 0

Is the JSON you posted the full JSON response you get from the server, or is it wrapped in an outer object? If it is wrapped in another object, then that could explain the problem. For example, if your JSON actually looks like this:

{ "response": { "probability": 0.01, "mean": 0, "variance": 0, "min": 0, "max": 0 } }

and you try to deserialize it into Tail_Metrics, then JSON.Net will not be able to match any of the properties, because they are all one level further down in the JSON. If you have set "IsRequired = true" on the properties then this will cause JSON.Net to throw the exception you are seeing. If you remove it, then JSON.Net will simply assign a default value of zero to the double properties in your class for which it can't find a match in the JSON. If all your data happens to be zero in the JSON anyway, then it will look like it's working even if it really is silently failing.

更多推荐

本文发布于:2023-04-24 21:14:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/e004db1d66cb6f38fba3083a49241c6d.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:概率   中找   属性   JSON   Path

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!