Skip to content

Commit fb6801a

Browse files
author
Bart Koelman
committed
Added docs for nullable reference types
1 parent c788cd7 commit fb6801a

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Nullability
2+
3+
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.
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+
## NRT turned off
8+
9+
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.
10+
11+
Example:
12+
```c#
13+
public sealed class Label : Identifiable<int>
14+
{
15+
[Attr]
16+
[Required]
17+
public string Name { get; set; }
18+
19+
[Attr]
20+
public string RgbColor { get; set; }
21+
22+
[HasOne]
23+
[Required]
24+
public Person Creator { get; set; }
25+
26+
[HasOne]
27+
public Label Parent { get; set; }
28+
29+
[HasMany]
30+
public ISet<TodoItem> TodoItems { get; set; }
31+
}
32+
```
33+
34+
## NRT turned on
35+
36+
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.
37+
38+
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 (!).
39+
40+
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.
41+
42+
Example:
43+
44+
```c#
45+
public sealed class Label : Identifiable<int>
46+
{
47+
[Attr]
48+
public string Name { get; set; } = null!;
49+
50+
[Attr]
51+
public string? RgbColor { get; set; }
52+
53+
[HasOne]
54+
public Person Creator { get; set; } = null!;
55+
56+
[HasOne]
57+
public Label? Parent { get; set; }
58+
59+
[HasMany]
60+
public ISet<TodoItem> TodoItems { get; set; } = new HashSet<TodoItem>();
61+
}
62+
```

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)