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

Edd*_*ddy 3 c# json json.net

我正在寻找有人指出这里明显的错误。

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

 Response response = new Response(input)
        {
            stuff = processedStuff;
        };
        responseMessage = JsonConvert.SerializeObject(response);
        return new OkObjectResult(responseMessage);
Run Code Online (Sandbox Code Playgroud)

这一切看起来都不错,并且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);
                }
Run Code Online (Sandbox Code Playgroud)

这会失败并显示Error converting value *the JSON string* to "Response" at line 1

Response两个应用程序中的类文件相同。我在这里犯了什么从来不明显和明显看不见的错误?

Bri*_*ers 5

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

responseMessage = JsonConvert.SerializeObject(response);   // serialize to JSON
return new OkObjectResult(responseMessage);                // implicit serialization here
Run Code Online (Sandbox Code Playgroud)

可能的解决方案:

  1. 允许隐式序列化完成其任务(推荐):

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

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

    var doubleSerializedJson = await response.Content.ReadAsStringAsync();
    var json = JsonConvert.DeserializeObject<string>(doubleSerializedJson);
    returned = JsonConvert.DeserializeObject<Response>(json);
    
    Run Code Online (Sandbox Code Playgroud)