【问题标题】:json.NET throwing an InvalidCastException deserializing a 2D arrayjson.NET 抛出 InvalidCastException 反序列化二维数组
【发布时间】:2015-10-17 23:41:17
【问题描述】:

我正在尝试从 json 字符串中反序列化 double 值的二维数组。以下代码复制了我的问题:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

// Here is the json string I'm deserializing:
string json = @"{
                    ""array2D"": [
                    [
                        1.2120107490162675, 
                        -0.05202334010360783, 
                        -0.9376574575207149
                    ], 
                    [
                        0.03548978958456018, 
                        1.322076093231865, 
                        -4.430964590987738
                    ], 
                    [
                        6.428633738739363e-05, 
                        -1.6407574756162617e-05, 
                        1.0
                    ]
                    ], 
                    ""y"": 180, 
                    ""x"": 94
                }";

// Here is how I deserialize the string:
JObject obj = JObject.Parse(json);

int x = obj.Value<int>("x");
int y = obj.Value<int>("y");

// PROBLEM: InvalidCastException occurs at this line:
double[,] array = obj.Value<double[,]>("array2D");

xy 这两个整数具有预期值 94180。但是当执行到// PROBLEM 行时,会出现以下异常:

An unhandled exception of type 
'System.InvalidCastException' 
occurred in Newtonsoft.Json.dll

Additional information: 
Cannot cast Newtonsoft.Json.Linq.JArray
to Newtonsoft.Json.Linq.JToken.

我应该如何使用 json.NET 才不会出现这个异常?

array 的期望值应该明确。

【问题讨论】:

    标签: c# arrays json casting json.net


    【解决方案1】:

    这行得通:

    JObject obj = JObject.Parse(json);
    double[,] array = obj["array2D"].ToObject<double[,]>();
    

    因为,根据@dbc,

    差异似乎没有很好的记录。 JToken.Value 基本上是针对原始类型的Convert.ChangeType,而ToObject() 实际上是反序列化的。

    【讨论】:

    • 确实有效。 JSON.NET 大师能否解释其中的区别?
    • @kdbanman - 差异似乎没有很好的记录。 JToken.Value&lt;T&gt; 基本上是针对原始类型的Convert.ChangeType,而ToObject() 实际上是反序列化的。
    • 感谢@dbc,大侦探!
    【解决方案2】:

    你可以这样做:

    JObject j = JObject.Parse(json);
    var list = j.SelectToken("array2D").ToString();
    var data = JsonConvert.DeserializeObject<double[,]>(list);
    

    这一行:

    JObject j = JObject.Parse(json);
    

    不反序列化数据,它只是将其解析为Object。您仍然需要告诉 JSON.NET 您希望将其序列化为哪种类型的对象。

    【讨论】:

    • 感谢您的回答!仅供参考:“你仍然需要告诉它什么类型的对象”这正是泛型方法 .Value&lt;double[,]&gt; 的类型参数应该做的事情。
    • (double[,])j.SelectToken("array2D"); 无法编译。从JTokendouble [,] 没有明确的案例。而且JsonConvert.DeserializeObject&lt;double[,]&gt;(list); 也无法编译,因为list 不是字符串或可隐式转换为字符串。
    • 我正在安装 Visual Studio,但无法对其进行测试。我忘记了 ToString()。再试一次,它会起作用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多