Skip to content

Commit 64f8224

Browse files
author
Bart Koelman
committed
Added docs for nullable reference types
1 parent a14472d commit 64f8224

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

docs/internals/queries.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ _since v4.0_
55
The query pipeline roughly looks like this:
66

77
```
8-
HTTP --[ASP.NET Core]--> QueryString --[JADNC:QueryStringParameterReader]--> QueryExpression[] --[JADNC:ResourceService]--> QueryLayer --[JADNC:Repository]--> IQueryable --[EF Core]--> SQL
8+
HTTP --[ASP.NET]--> QueryString --[JADNC:QueryStringParameterReader]--> QueryExpression[] --[JADNC:ResourceService]--> QueryLayer --[JADNC:Repository]--> IQueryable --[EF Core]--> SQL
99
```
1010

1111
Processing a request involves the following steps:

docs/usage/options.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ Because we copy resource properties into an intermediate object before serializa
102102

103103
## Enable ModelState Validation
104104

105-
If you would like to use ASP.NET Core ModelState validation into your controllers when creating / updating resources, set `ValidateModelState` to `true`. By default, no model validation is performed.
105+
If you would like to use ASP.NET ModelState validation into your controllers when creating / updating resources, set `ValidateModelState` to `true`. By default, no model validation is performed.
106+
107+
How nullability affects ModelState validation is described [here](~/usage/resources/nullability.md).
106108

107109
```c#
108110
options.ValidateModelState = true;

docs/usage/resources/nullability.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Nullability in resources
2+
3+
Properties on a resource class can be declared as nullable or non-nullable. This affects both ASP.NET ModelState validation and the way Entity Framework Core generates database columns.
4+
5+
Note that ModelState validation is turned off by default. It can be enabled in [options](~/usage/options.md#enable-modelstate-validation).
6+
7+
# Value types
8+
9+
When ModelState validation is enabled, non-nullable value types will **not** trigger a validation error when omitted in the request body.
10+
To make JsonApiDotNetCore return an error when such a property is missing on resource creation, declare it as nullable and annotate it with `[Required]`.
11+
12+
Example:
13+
14+
```c#
15+
public sealed class User : Identifiable<int>
16+
{
17+
[Attr]
18+
[Required]
19+
public bool? IsAdministrator { get; set; }
20+
}
21+
```
22+
23+
This makes EF Core generate non-nullable columns. And model errors are returned when nullable fields are omitted.
24+
25+
# Reference types
26+
27+
When the [nullable reference types](https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references) (NRT) compiler feature is enabled, it affects both ASP.NET ModelState validation and Entity Framework Core.
28+
29+
## NRT turned off
30+
31+
When NRT is turned off, use `[Required]` on required attributes and relationships. This makes EF Core generate non-nullable columns. And model errors are returned when required fields are omitted.
32+
33+
Example:
34+
35+
```c#
36+
public sealed class Label : Identifiable<int>
37+
{
38+
[Attr]
39+
[Required]
40+
public string Name { get; set; }
41+
42+
[Attr]
43+
public string RgbColor { get; set; }
44+
45+
[HasOne]
46+
[Required]
47+
public Person Creator { get; set; }
48+
49+
[HasOne]
50+
public Label Parent { get; set; }
51+
52+
[HasMany]
53+
public ISet<TodoItem> TodoItems { get; set; }
54+
}
55+
```
56+
57+
## NRT turned on
58+
59+
When NRT is turned on, use nullability annotations (?) on attributes and relationships. This makes EF Core generate non-nullable columns. And model errors are returned when non-nullable fields are omitted.
60+
61+
The [EF Core guidance on NRT](https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types) recommends to use constructor binding to initialize non-nullable properties, but JsonApiDotNetCore does not support that. For required navigation properties, it suggests to use a non-nullable property with a nullable backing field. JsonApiDotNetCore does not support that either. In both cases, just use the null-forgiving operator (!).
62+
63+
When ModelState validation is turned on, to-many relationships must be assigned an empty collection. Otherwise an error is returned when they don't occur in the request body.
64+
65+
Example:
66+
67+
```c#
68+
public sealed class Label : Identifiable<int>
69+
{
70+
[Attr]
71+
public string Name { get; set; } = null!;
72+
73+
[Attr]
74+
public string? RgbColor { get; set; }
75+
76+
[HasOne]
77+
public Person Creator { get; set; } = null!;
78+
79+
[HasOne]
80+
public Label? Parent { get; set; }
81+
82+
[HasMany]
83+
public ISet<TodoItem> TodoItems { get; set; } = new HashSet<TodoItem>();
84+
}
85+
```

docs/usage/toc.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# [Resources](resources/index.md)
22
## [Attributes](resources/attributes.md)
33
## [Relationships](resources/relationships.md)
4+
## [Nullability](resources/nullability.md)
45

56
# Reading data
67
## [Filtering](reading/filtering.md)

0 commit comments

Comments
 (0)