THB*_*BFT 17 c# json.net .net-core system.text.json
我已经梳理了MS 文档,但找不到与NewtonSoft JsonPropertyRequired等效的属性。
我要找的是这个:
public class Videogame
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我是否只是遗漏了某些东西,或者 Microsoft 库中不存在这种级别的验证?
Sim*_*ver 11
前置:
特别提到了这个问题Required.Always
,这Newtonsoft.Json
将需要该属性并不允许空值(例如"firstName": null
不允许)。
这System.Text.Json
相当于[JsonRequired]
(参见这篇文章),因为它必须有一个值,并且不允许为 null。
官方迁移文档目前在其他相关的 Newtonsoft 功能上非常薄弱。例如,Newtonsoft.Json
您有以下四个枚举选项Required
(这是 JsonProperty 上使用的属性):
Default The property is not required. The default state.
AllowNull The property must be defined in JSON but can be a null value.
Always The property must be defined in JSON and cannot be a null value.
DisallowNull The property is not required but it cannot be a null value.
Run Code Online (Sandbox Code Playgroud)
需要注意的是,这不是[JsonRequired]
属性(来自 Newtonsoft),这意味着“...始终序列化成员,并要求成员具有值。”。
我不会尝试为上述内容制作一个映射表,因为我几乎肯定会弄错 - 而且我实际上认为这是不可能的。
然而,还有另一个相关属性 [JsonIgnore(Condition = JsonIgnoreCondition.XXXX]) [attribute][3] in
System.Text.Json` 会影响序列化,并且可能更有用。
如果为 null,则使用[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
不会将值输出到 JSON。所以这有点类似于Required.AllowNull
(但你不会[JsonRequired]
再使用,因为它实际上并不需要!)。
最重要的是,这两个库之间并不完全相似,您使用它的方式将极大地影响迁移的难易程度。仔细计划!
.NET 7(2022 年 11 月)现在有了自己的版本[JsonRequired]
,许多人在看到如下错误时都会第一次发现:
“JsonRequired”是“Newtonsoft.Json.JsonRequiredAttribute”和“System.Text.Json.Serialization.JsonRequiredAttribute”之间的不明确引用
这可能是由于文件中包含以下两个 using 语句造成的:
using System.Text.Json.Serialization;
using Newtonsoft.Json;
Run Code Online (Sandbox Code Playgroud)
最简单、最安全的快速解决方案(如果您想继续使用 Newtonsoft)是搜索和替换并进行以下两个替换:
[JsonRequired] => [Newtonsoft.Json.JsonRequired]
[JsonRequired( => [Newtonsoft.Json.JsonRequired(
Run Code Online (Sandbox Code Playgroud)
仅当您的所有代码当前均为 .NET 6(此属性的使用必须来自 Newtonsoft)时,才能保证此功能有效。如果您要组合 .NET 6 和 .NET 7 项目中的代码,请务必小心。这就是我计划做的事情,以避免将来我切换时出现混乱(实际上我不打算这么做)。
如果您能够做到这一点,有一篇关于完全迁移到的更一般性的文章。System.Text.Json
Kyl*_*lan 10
从5.0开始,您可以使用构造函数来实现这一点。任何异常都会在反序列化期间出现。
public class Videogame
{
public Videogame(string name, int? year)
{
this.Name = name ?? throw new ArgumentNullException(nameof(name));
this.Year = year ?? throw new ArgumentNullException(nameof(year));
}
public string Name { get; }
[NotNull]
public int? Year { get; }
}
Run Code Online (Sandbox Code Playgroud)
注意:如果 JSON 中缺少构造函数参数,该库不会抛出错误。它仅使用类型的默认值(因此0
对于int
)。如果您想处理这种情况,最好使用可空值类型。
此外,构造函数参数的类型必须与您的字段/属性完全匹配,因此不幸的是,不能从int?
to进行int
。我发现 System.Diagnostics.CodeAnalysis 命名空间中的分析属性[NotNull]
和/或[DisallowNull]
可以减轻这方面的不便。
与.NET Core 3.0 不同。唯一支持的是:
JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonPropertyNameAttribute
Run Code Online (Sandbox Code Playgroud)
更新:在.NET 5.0 中,集合是
JsonConstructorAttribute
JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonIncludeAttribute
JsonNumberHandlingAttribute
JsonPropertyNameAttribute
Run Code Online (Sandbox Code Playgroud)
不幸的是,即使HandleNull => true
在如何为 .NET 中的 JSON 序列化(编组)编写自定义转换器中显示的自定义转换器也无法工作,因为如果不存在读取和写入方法中的属性不被调用(在 5.0 中测试,并且在3.0)
public class Radiokiller
{
[JsonConverter(typeof(MyCustomNotNullConverter))]
public string Name { get; set; }
}
public class MyCustomNotNullConverter : JsonConverter<string>
{
public override bool HandleNull => true;
public override string Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) =>
reader.GetString() ?? throw new Exception("Value required.");
public override void Write(
Utf8JsonWriter writer,
string value,
JsonSerializerOptions options) =>
writer.WriteStringValue(value);
}
Run Code Online (Sandbox Code Playgroud)
var json = "{}";
var o = JsonSerializer.Deserialize<Radiokiller>(json); // no exception :(
json = "{ \"Name\" : null}";
o = JsonSerializer.Deserialize<Radiokiller>(json); // throws
Run Code Online (Sandbox Code Playgroud)
请试试我作为 System.Text.Json 扩展编写的这个库,以提供缺少的功能:https : //github.com/dahomey-technologies/Dahomey.Json。
您将找到对 JsonRequiredAttribute 的支持。
public class Videogame
{
[JsonRequired(RequirementPolicy.Always)]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
通过调用命名空间 Dahomey.Json 中定义的扩展方法 SetupExtensions 的 JsonSerializerOptions 来设置 json 扩展。然后使用常规 Sytem.Text.Json API 反序列化您的类。
JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();
const string json = @"{""Name"":""BGE2""}";
Videogame obj = JsonSerializer.Deserialize<Videogame>(json, options);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6663 次 |
最近记录: |