I had a requirement where I want to enforce some property values to be present
before deserializing the JSON string. And with .NET 7, you can do that pretty
easily (another reason to move to .NET 7).
In this post, let's see how we can enforce the required properties for
deserialization. There are three ways,
Failing to provide a required property will throw a JsonException.
Let's have a look.
By adding the required modifier
Consider the following POCO class. Here I have applied required modifier to FirstName and LastName.
public record Person
{
public required string FirstName { get; set; }
public string? MiddleName { get; set; }
public required string LastName { get; set; }
}
And let's try to deserialize the following string.
string @string = """
{
"FirstName": "John",
"LastName": "Doe"
}
""";
try
{
Person? person = JsonSerializer.Deserialize<Person>(@string);
}
catch (JsonException jsonException)
{
Console.WriteLine(jsonException.Message);
}
The above code is successfully deserializing the string into a person. Because
the string has required properties set.
Now let's try the below. I am removing the LastName from JSON string.
string @string = """
{
"FirstName": "John"
}
""";
try
{
Person? person = JsonSerializer.Deserialize<Person>(@string);
}
catch (JsonException jsonException)
{
Console.WriteLine(jsonException.Message);
// JSON deserialization for type 'Person' was missing required properties, including the following: LastName
}
This will fail because our string doesn't contain the LastName property.
We can achieve the same result as above by using JsonRequiredAttribute. So instead of adding required modifier, we can decorate the property with JsonRequiredAttribute.
public record Person
{
[JsonRequired]
public string FirstName { get; set; }
public string? MiddleName { get; set; }
[JsonRequired]
public string LastName { get; set; }
}
This is kind of a more advanced approach.
string @string = """
{
"FirstName": "John"
}
""";
var jsonSerializerOptions = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers =
{
static typeInfo =>
{
if (typeInfo.Kind != JsonTypeInfoKind.Object)
{
return;
}
foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
{
propertyInfo.IsRequired = propertyInfo.Name switch
{
nameof(Person.FirstName) or nameof(Person.LastName) => true,
_ => false
};
}
}
}
}
};
try
{
// This time we are passing the jsonSerializerOptions
Person? person = JsonSerializer.Deserialize<Person>(@string, jsonSerializerOptions);
}
catch (JsonException jsonException)
{
Console.WriteLine(jsonException.Message);
// JSON deserialization for type 'Person' was missing required properties, including the following: LastName
}
The above will also throw a JsonException with a message saying Required properties aren't set.
Hope this helps.
Happy Coding.
Regards,
Jaliya