问题描述
考虑代码...
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; }
}
为什么没有将数据正确反序列化到 User
对象中?我还通过 DotNetFiddle 验证了该行为,以防它是我系统本地的问题.不抛出异常.
Why isn't the data being deserialized properly into the User
object? I also verified the behavior via DotNetFiddle in case it was an issue local to my system. No exception is thrown.
我的实际实现是在我 return Created("user", newUser)
[ApiController] 的 [HttpPost]
操作中读取的>.它是通过 _httpClient.PostAsync
在我的 MVC/Razor 项目中调用的.我验证了 Created
返回到 PostAsync
调用时的值是正确的,但无论如何,从响应正文中解析的值仅包含默认值(实际 ID 是Guid
).
My actual implementation is read from an [ApiController]
's [HttpPost]
action after I return Created("user", newUser)
. It is called in my MVC/Razor project via _httpClient.PostAsync
. I verified the values are correct when Created
is returned to the PostAsync
call, but no matter what, the value parsed from the response body contains only default values (the actual ID is a Guid
).
我最初认为这可能是与 UTF8 相关的问题,因为那是我发布到 ApiController
的 StringContent
的编码.引用了 UTF8 反序列化 这里,但我无法从 HttpContent
的 IO.Stream 到 ReadOnlySpan
或 Utf8JsonReader
.
I initially thought it might have been an UTF8 related issue, as that is the encoding for the StringContent
I post to the ApiController
. UTF8 deserialization is referenced here, but I had trouble getting from the IO.Stream of the HttpContent
to a ReadOnlySpan
or Utf8JsonReader
.
我找到了这个项目在搜索时,这让我认为它应该可以按预期工作.
I found this project while searching, which makes me think it should work as I expected.
推荐答案
你的问题是 System.Text.Json
默认区分大小写,所以 "id": 9
(全部小写)未映射到 Id
属性.从 文档:
Your problem is that System.Text.Json
is case-sensitive by default, so "id": 9
(all lowercase) is not mapped to the Id
property. From the docs:
不区分大小写的属性匹配
默认情况下,反序列化会在 JSON 和目标对象属性之间查找区分大小写的属性名称匹配.要更改该行为,请设置 JsonSerializerOptions.PropertyNameCaseInsensitive
到 true
:
By default, deserialization looks for case-sensitive property name matches between JSON and the target object properties. To change that behavior, set JsonSerializerOptions.PropertyNameCaseInsensitive
to true
:
注意:web 默认 不区分大小写.
Note: The web default is case-insensitive.
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
};
var weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString, options);
所以你也需要这样做:
var u = JsonSerializer.Deserialize<User>(str, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
演示小提琴 #1 这里.
您可以在 ASP.NET Core 3.0 中配置启动时的选项,如 How to set json serializer settings in asp 中所示.net 核心 3?:
You can configure the option on startup in ASP.NET Core 3.0 as shown in How to set json serializer settings in asp.net core 3?:
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
或者,您可以申请 [JsonPropertyName("id")]
到您的模型:
Alternatively you could apply [JsonPropertyName("id")]
to your model:
public class User {
[JsonPropertyName("id")]
public int Id { get; set; }
}
演示小提琴 #2 这里.
这篇关于JsonSerializer.Deserialize 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!