Json.Net仅在Visual Studio

时间:2016-06-05 13:16:48

标签: c# visual-studio-2015 json.net deserialization

我有一些奇怪的行为,我无法弄清楚。

我使用WCF服务将文件保存到某个数据库表。 WCF服务有一个方法,它将JSON字符串作为参数。在这种情况下,JSON是一个序列化命令,其中包含List<FileData>和其他属性。 WCF服务反序列化JSON并为此特定命令运行CommandHandler

最终用户在尝试上传大小为52 MB的文件时遇到了错误。 WCF服务返回404错误。

我能够在Visual Studio中重现这一点。根据此article更改配置文件后,404消失了。

但现在出现了一个新的异常:当命令成功序列化客户端,由WCF成功处理后,反序列化抛出OutOfMemoryException。这是堆栈跟踪的顶部:

  

at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append,Int32 charsRequired)      at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append)      at Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char quote)      at Newtonsoft.Json.JsonTextReader.ParseString(Char quote)      at Newtonsoft.Json.JsonTextReader.ParseValue()      at Newtonsoft.Json.JsonTextReader.ReadInternal()      at Newtonsoft.Json.JsonReader.ReadAsBytesInternal()      at Newtonsoft.Json.JsonTextReader.ReadAsBytes()      at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader,JsonContract contract,Boolean hasConverter)

我写了一个单元测试来证明这个bug。但是,在这个测试通过的情况下,换句话说,没有抛出OutOfMemoryException

为了完整性而进行的测试:

    [TestMethod]
    public void LoadBigFile_SerializeDeserialize_DoesntThrowOutOfMemoryException()
    {
        // Arrange
        byte[] bytes = new byte[80000000];
        Random r = new Random(23);
        r.NextBytes(bytes);

        var command = new SomeCommand(new List<FileData>
        {
            new FileData(
                fileFullName: @"D:\SomePdfFile.pdf",
                modifyDate: DateTime.MaxValue,
                data: bytes
                )
        });

        var data = JsonConvert.SerializeObject(command);

        // Act
        var deserializedCommand = 
              JsonConvert.DeserializeObject<SomeCommand>(data);

        // Assert
        Assert.AreEqual(bytes.Length, deserializedCommand.Files.First().Data.Length);
    }

所以,我抓住了机会,改变了生产中的配置文件,并尝试上传相同的文件。这才有效!!!没有OutOfMemoryException

现在我的问题是,为什么OutOfMemoryException只发生在Visual Studio中,而VS的同一个实例中的单元测试却没有?感觉有点奇怪,我无法在Visual Studio中测试上传大文件,而它在生产中工作。请注意,我也尝试在Release模式下运行Debug。

一些细节:

  • 使用Json.Net 7.0.1
  • Visual Studio 2015,更新2
  • WCF在本地IIS Express中托管,生产中的IIS
  • Windows 10最新版本64位
  • 生产服务器Windows server 2008 R2 64位
  • .Net Framework 4.5.2

1 个答案:

答案 0 :(得分:5)

我在单元测试中通过将byte[] bytes = new byte[80000000];更改为byte[] bytes = new byte[52000000];并在循环中运行(2次)来复制{{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,63}}。测试运行器是32位。

回到IIS Express - 我认为你使用的是32位版本。您可以在

更改此设置
  

工具|选项|项目和解决方案|网站项目|使用64位版本的IIS Express

相关问题