无法在两端使用相同的类在C#中反序列化JSON

发布时间:2020-07-07 17:24

我正在寻找可以指出此处明显错误的人。

C#应用程序中的.NET Core对另一个此类应用程序进行HTTP调用。执行一些处理,然后发送响应:

 Response response = new Response(input)
        {
            stuff = processedStuff;
        };
        responseMessage = JsonConvert.SerializeObject(response);
        return new OkObjectResult(responseMessage);

一切看起来不错,responseMessage包含有效的JSON(根据我发现的在线JSON检查器)。

在另一端,这样接收:

Response returned = new Response();
var response = await client.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    var json = await response.Content.ReadAsStringAsync();
                    returned = JsonConvert.DeserializeObject<Response>(json);
                }

此操作失败,并显示Error converting value *the JSON string* to "Response" at line 1

Response是两个应用程序中的相同类文件。我在这里犯了什么从未出现过的,显然看不见的错误?

回答1

您犯的无形错误是对结果进行双序列化。 OkObjectResult的约定是它将自动将结果对象序列化为协商的内容类型(例如JSON或XML)并返回OK状态。您首先要序列化对象,然后将序列化的字符串传递给OkObjectResult,这样它最终会被序列化两次。

responseMessage = JsonConvert.SerializeObject(response);   // serialize to JSON
return new OkObjectResult(responseMessage);                // implicit serialization here

可能的解决方案:

  1. 允许隐式序列化做它的事情(推荐):

    return new OkObjectResult(response);   // implicit serialization of response object
    
  2. 使用ContentResult代替(如果需要特殊的序列化处理,则很好):

    responseMessage = JsonConvert.SerializeObject(response);   // serialize to JSON
    return new ContentResult()
    {
        Content = responseMessage,
        ContentType = "application/json",
        StatusCode = 200
    };
    
  3. 在接收端反序列化两次(作为最后的手段,即您不控制服务器):

    var doubleSerializedJson = await response.Content.ReadAsStringAsync();
    var json = JsonConvert.DeserializeObject<string>(doubleSerializedJson);
    returned = JsonConvert.DeserializeObject<Response>(json);
    
回答2

检查返回的字符串是否未包装在OkObjectResult对象中。

回答3

据我所知,您不需要序列化和反序列化,该框架已经处理了所有事情。如果需要,您始终可以反序列化为匿名类型,也可以从对象强制转换它。 https://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm

如果您可以共享响应类,我也会提供帮助,因为这很可能是问题的一部分。

回答4

作为一个足以记住辛普森一家公司成立时的人,我只能以传统方式回答:

D'哦!

使用上面的响应者所描述的隐式序列化解决了该问题。