Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I've combed through the MS docs but cannot find an attribute equivalent to the NewtonSoft JsonPropertyRequired.

What I'm looking for is this:

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

Am I just missing something or does this level of validation not exist in the Microsoft library?

like image 631
THBBFT Avatar asked Oct 18 '19 02:10

THBBFT


People also ask

Which is better Newtonsoft JSON or System text JSON?

Json does case-insensitive property name matching by default. The System. Text. Json default is case-sensitive, which gives better performance since it's doing an exact match.

Which of the following attributes are required to ignore properties for JSON serializer?

To ignore individual properties, use the [JsonIgnore] attribute.

What is JSON property C#?

JsonPropertyAttribute indicates that a property should be serialized when member serialization is set to opt-in. It includes non-public properties in serialization and deserialization. It can be used to customize type name, reference, null, and default value handling for the property value.

What is JSON property name?

The Jackson Annotation @JsonProperty is used on a property or method during serialization or deserialization of JSON. It takes an optional 'name' parameter which is useful in case the property name is different than 'key' name in JSON.


2 Answers

Not as of .NET Core 3.0. The only ones supported are:

JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonPropertyNameAttribute

Update: In .NET 5.0 the set is

JsonConstructorAttribute
JsonConverterAttribute
JsonExtensionDataAttribute
JsonIgnoreAttribute
JsonIncludeAttribute
JsonNumberHandlingAttribute
JsonPropertyNameAttribute

Unfortunately even a custom converter with HandleNull => true shown in How to write custom converters for JSON serialization (marshalling) in .NET won't work because if the property in not present Read and Write methods are not called (tested in 5.0, and a modified version in 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
like image 89
tymtam Avatar answered Sep 22 '22 08:09

tymtam


Please try this library I wrote as an extension to System.Text.Json to offer missing features: https://github.com/dahomey-technologies/Dahomey.Json.

You will find support for JsonRequiredAttribute.

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

Setup json extensions by calling on JsonSerializerOptions the extension method SetupExtensions defined in the namespace Dahomey.Json. Then deserialize your class with the regular Sytem.Text.Json API.

JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();

const string json = @"{""Name"":""BGE2""}";
Videogame obj = JsonSerializer.Deserialize<Videogame>(json, options);
like image 41
Michaël Catanzariti Avatar answered Sep 19 '22 08:09

Michaël Catanzariti