我有一个项目,我需要在其中读取来自 Http 服务器的响应。响应是在 Json 中。来自该 json 的对象图反序列化为大部分工作,但是最低级别的数组失败,留下空值。

我在下面创建了可以粘贴到空白测试项目中并运行的代码。唯一的测试失败了,我不知道为什么。示例 Json 是顶部的 const 字符串。

我发现 JavaScriptSerializer 中的 System.Web.Extensions 确实有效(当我使用 List 而不是数组时)。但是,Json.Net 等效项不起作用。下面的示例中有两个测试,Newtonsoft 一个失败了,但为什么呢?我遗漏了哪些 Newtonsoft 文档?

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using System.Collections.Generic;

/// <summary>
/// Unit Test project that also includes a reference to System.Web.Extensions.
/// Also includes Newtonsoft from NuGet.
/// The constant `_downloadRootObjectEg` holds the sample json.
/// </summary>
namespace Savaged
{
    [TestClass]
    public class DownloadDeserialisationTest
    {
        private const string _downloadRootObjectEg = "{ \"error\": \"\", \"success\": true, \"data\": [{ \"data\": [{ \"TextSearched\": \"New product\", \"TextFound\": \"New product\", \"data \": [{ \"x\": 0.585, \"y\": 0.21496437 }, { \"x\": 0.63666666, \"y\": 0.21496437 }, { \"x\": 0.6933333, \"y\": 0.23515439 } ], \"Page\": 16 }, { \"TextSearched\": \"Expiry\", \"TextFound\": \"Expiry\", \"data \": [{ \"x\": 0.6666667, \"y\": 0.16270784 }, { \"x\": 0.7133333, \"y\": 0.16270784 }, { \"x\": 0.7133333, \"y\": 0.18052256 }, { \"x\": 0.6666667, \"y\": 0.18052256 } ], \"Page\": 39 }, { \"TextSearched\": \"Expiry\", \"TextFound\": \"Expiry\", \"data \": [{ \"x\": 0.47833332, \"y\": 0.6686461 }, { \"x\": 0.52166665, \"y\": 0.6686461 }, { \"x\": 0.52166665, \"y\": 0.6864608 }, { \"x\": 0.47833332, \"y\": 0.6864608 } ], \"Page\": 43 } ], \"context\": { \"FileLocation\": \"Product-09-08-2007.pdf\", \"ID\": 1, \"Type\": \"product\" } }, { \"data\": [{ \"TextSearched\": \"New product\", \"TextFound\": \"New product\", \"data \": [{ \"x\": 0.585, \"y\": 0.21496437 }, { \"x\": 0.63666666, \"y\": 0.21496437 }, { \"x\": 0.6933333, \"y\": 0.23515439 }, { \"x\": 0.6433333, \"y\": 0.23515439 } ], \"Page\": 16 }, { \"TextSearched\": \"Expiry\", \"TextFound\": \"Expiry\", \"data \": [{ \"x\": 0.6666667, \"y\": 0.16270784 }, { \"x\": 0.7133333, \"y\": 0.16270784 }, { \"x\": 0.7133333, \"y\": 0.18052256 }, { \"x\": 0.6666667, \"y\": 0.18052256 } ], \"Page\": 39 } ], \"context\": { \"FileLocation\": \"Product-09-08-2007.pdf\", \"ID\": 1, \"Type\": \"product\" } } ], \"count\": 2 }";

        [TestMethod]
        public void DeserialiseTest()
        {
            var downloadRootObject =
                JsonConvert.DeserializeObject<DownloadRootObject>(_downloadRootObjectEg);

            Assert.IsNotNull(downloadRootObject.Data[0].Data[0].Data, "Why?");
        }

        [TestMethod]
        public void JavaScriptSerializerTest()
        {
            var downloadRootObject = new System.Web.Script.Serialization.
                JavaScriptSerializer().Deserialize<DownloadRootObject>(_downloadRootObjectEg);

            Assert.IsNotNull(downloadRootObject.Data[0].Data[0].Data, "Why?");
        }
    }

    #region Concrete implementation

    public abstract class RootObjectBase
    {
        public string Error { get; set; }

        public bool Success { get; set; }
    }

    public class DownloadRootObject : RootObjectBase
    {
        public DownloadRootObject()
        {
            Data = new List<WordSearch>();
        }

        [JsonConstructor]
        public DownloadRootObject(List<WordSearch> data)
        {
            Data = data;
        }

        public List<WordSearch> Data { get; set; }

        public int Count { get; set; }
    }

    public class WordSearch
    {
        public WordSearch()
        {
            Data = new List<Match>();
        }

        [JsonConstructor]
        public WordSearch(Context context, List<Match> data)
        {
            Context = context;
            Data = data;
        }

        public Context Context { get; set; }

        public List<Match> Data { get; set; }
    }

    public class Context
    {
        public string FileLocation { get; set; }

        public int ID { get; set; }

        public string Type { get; set; }
    }

    public class Match
    {
        public Match()
        {
            Data = new List<PointF>();
        }

        [JsonConstructor]
        public Match(List<PointF> data)
        {
            Data = data;
        }

        public int Page { get; set; }

        // TODO switch this to System.Drawing.PointF
        public List<PointF> Data { get; set; }

        public string TextSearched { get; set; }

        public string TextFound { get; set; }
    }

    public class PointF
    {
        public float X { get; set; }

        public float Y { get; set; }
    }

    #endregion
}

非常感谢所有帮助!

最佳答案

从我所看到的,提到的列表没有被反序列化,因为最低级别的“数据”属性中有一个尾随空格。

 \"data \": [{ \"x\": 0.585, \"y\": 0.21496437 }

但实际上应该是:
 \"data\": [{ \"x\": 0.585, \"y\": 0.21496437 }

关于c# - 第三级的 Object List<T> 不使用 Newtonsoft Json.Net 反序列化(在文档中找不到解决方案),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52740469/

10-11 23:04
查看更多