c# - System.Text.Json 反序列化 uint
问题描述
所以看起来新的 Json 库没有反序列化(甚至为此序列化)UInt32
类型。在 MVC 应用程序中,以下内容在 POST 的有效负载中发送:
{
"Overrides":{
},
"Directions":{
"data1" : "data2"
},
"ModeId": "1782354543",
"TestNumber" : 10
}
它应该被序列化的类是这样的:
public class Payload
{
public uint ModeId;
public Dictionary<string, string> Directions{ get; set; } = new();
public Dictionary<string, string> Overrides { get; set; } = new();
public int TestNumber { get; set; }
}
但是当收到请求时,ModeId
为 0。我尝试根据我在这里找到的单元测试添加自定义转换器
像这样:
public class UIntConverter : JsonConverter<uint>
{
public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
string stringValue = reader.GetString();
if (uint.TryParse(stringValue, out uint x))
{
return x;
}
}
if (reader.TokenType == JsonTokenType.Number)
{
return reader.GetUInt32();
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOptions options)
{
writer.WriteNumberValue(value);
}
}
并像这样注册它:
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.WriteIndented = false;
options.JsonSerializerOptions.IgnoreNullValues = true;
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
options.JsonSerializerOptions.Converters.Insert(options.JsonSerializerOptions.Converters.Count,new UIntConverter());
});
我什至无法使用相同的转换器将我的类序列化为字符串。它只是忽略了 uid 属性。
var payload = new Payload()
{
Directions = new Directions
{
{"data1", "data2" }
},
ModeId = 1782354543,
TestNumber = 10
}
//then try to serialize
var defaultJsonSerializerSettings = new JsonSerializerOptions()
{
IgnoreNullValues = true,
WriteIndented = false,
PropertyNamingPolicy = null,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Converters = { new UIntConverter()}
};
Serializer.Serialize(payload, typeof(Payload), defaultJsonSerializerSettings);
它序列化所有内容,除了完全被忽略的 uint 属性。
您对 uint 属性的序列化/反序列化有何建议/建议?
[更新]:问题是我试图序列化/反序列化一个字段,而不是答案中指出的具有公共访问器的属性。碰巧 field 是 type uint
。
解决方案
如果您使用的是 .NET 5,或者如果 - 正如@Jimi 指出的那样 - install <PackageReference Include="System.Text.Json" Version="5.0.2" />
,则可以使用IncludeFields
andAllowReadingFromString
选项:
var serializeOptions = new JsonSerializerOptions
{
IncludeFields = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
var p = JsonSerializer.Deserialize<Payload>(json, serializeOptions);
在 .NET5 之前,您需要将 ModeId 更改为属性。
顺便提一句。您可以在没有转换器的情况下处理字符串/整数:
public string ModeId {get; set}
public uint ModeIdParsed => uint.Parse(ModeId);
如果你需要保留ModeId
名字,那么你可以
public class Payload
{
[JsonPropertyName("ModeId")]
public string modeId {get;set;}
[JsonIgnore]
public uint ModeId => uint.Parse(modeId);
}
不幸的是,在 3.1 中,您需要将字符串变体公开(反序列化私有可从 v5 获得)。
推荐阅读
- php - 从 Docker 容器内部如何连接到 WSL2 发行版
- payment-gateway - Braintree 支持分期付款吗?
- python-3.x - 点击“加载更多新闻”按钮后 Python 抓取页面
- python - Python 请求遇到状态代码 406 和错误消息“请求不允许”
- mysql - 有多少电影只属于一种类型?
- javascript - 在 objection.js 中使用 json-schema 处理验证的正确方法是什么?
- javascript - 在标题键嵌套对象vue js上搜索和替换字符串
- flutter - 在字符串的单个字母上颤动触摸事件
- mysql - MySQL8 允许多少个 JOIN?
- mongodb - 在 mongodb 中创建唯一 id,每次插入都会增加