新的“System.Text.Json”是否具有必需的 属性 属性?

Does the new `System.Text.Json` have a required property attribute?

我梳理了 MS docs but cannot find an attribute equivalent to the NewtonSoft JsonPropertyRequired

我要找的是这个:

public class Videogame
{
    [JsonProperty(Required = Required.Always)]
    public string Name { get; set; }
}

我是不是遗漏了什么,或者 Microsoft 库中不存在这种级别的验证?

.NET Core 3.0 开始没有。唯一支持的是:

JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonPropertyNameAttribute

更新:在.NET 5.0中集合是

JsonConstructorAttribute
JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonIncludeAttribute
JsonNumberHandlingAttribute
JsonPropertyNameAttribute

不幸的是,即使 How to write custom converters for JSON serialization (marshalling) in .NET 中显示的带有 HandleNull => true 的自定义转换器也无法工作,因为如果 属性 不存在,则不会调用读取和写入方法(在 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);

}
var json = "{}";
var o = JsonSerializer.Deserialize<Radiokiller>(json); // no exception :(

json = "{  \"Name\" : null}";
o = JsonSerializer.Deserialize<Radiokiller>(json); // throws

请试试我写的这个库作为 System.Text.Json 的扩展来提供缺少的功能:https://github.com/dahomey-technologies/Dahomey.Json.

您会发现对 JsonRequiredAttribute 的支持。

public class Videogame
{
    [JsonRequired(RequirementPolicy.Always)]
    public string Name { get; set; }
}

通过在 JsonSerializerOptions 上调用命名空间 Dahomey.Json 中定义的扩展方法 SetupExtensions 来设置 json 扩展。然后使用常规 Sytem.Text.Json API.

反序列化您的 class
JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();

const string json = @"{""Name"":""BGE2""}";
Videogame obj = JsonSerializer.Deserialize<Videogame>(json, options);

我正在使用 System.ComponentModel.DataAnnotations 中附带的通用 [Required] 属性。我已经将它与 Newtonsoft.JsonSystem.Text.Json 一起使用了。

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; }
}

N.B。如果 JSON 中缺少构造函数参数,库将不会抛出错误。它只使用类型的默认值(因此 0 对应 int)。如果您想处理这种情况,最好使用可为 null 的值类型。

此外,构造函数参数的类型必须与您的 fields/properties 完全匹配,所以很遗憾,不能从 int?int。我发现分析属性 [NotNull] and/or [DisallowNulls] 减少了不便。