JsonSerializer.Deserialize 失败

t.j*_*.j. 10 c# asp.net-core-mvc .net-core-3.1 system.text.json

考虑代码...

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        int id = 9;
        string str = "{\"id\": " + id + "}";
        var u = JsonSerializer.Deserialize<User>(str);
        Console.WriteLine($"User ID: {u.Id}, Correct: {id == u.Id}");  // always 0/init/default value
    }
}


public class User {
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

为什么数据没有正确反序列化到User对象中?我还通过DotNetFiddle验证了该行为,以防它是我系统的本地问题。不会抛出任何异常。

我的实际执行是从读[ApiController][HttpPost]后我的行动return Created("user", newUser)。它在我的 MVC/Razor 项目中通过_httpClient.PostAsync. 我在Created返回到PostAsync调用时验证了这些值是正确的,但无论如何,从响应正文解析的值仅包含默认值(实际 ID 是 a Guid)。

我最初认为这可能是与 UTF8 相关的问题,因为这是StringContent我发布到ApiController. 此处引用UTF8 反序列化,但我无法从 IO.StreamHttpContent到 a ReadOnlySpanor Utf8JsonReader

我在搜索时发现了这个项目,这让我觉得它应该按我的预期工作。

dbc*_*dbc 20

您的问题是System.Text.Json默认情况下区分大小写,因此"id": 9(全部小写)未映射到该Id属性。从文档

不区分大小写的属性匹配

默认情况下,反序列化在 JSON 和目标对象属性之间查找区分大小写的属性名称匹配。要更改该行为,请设置JsonSerializerOptions.PropertyNameCaseInsensitivetrue

注意:Web 默认不区分大小写。

var options = new JsonSerializerOptions
{
   PropertyNameCaseInsensitive = true,
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);
Run Code Online (Sandbox Code Playgroud)

所以你也需要这样做:

var u = JsonSerializer.Deserialize<User>(str, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Run Code Online (Sandbox Code Playgroud)

演示小提琴 #1在这里

您可以在 ASP.NET Core 3.0 中配置启动时的选项,如如何在 ASP.NET Core 3 中设置 json 序列化程序设置中所示

services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
Run Code Online (Sandbox Code Playgroud)

或者,您可以应用于[JsonPropertyName("id")]您的模型:

public class User {
    [JsonPropertyName("id")]
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

演示小提琴 #2在这里