Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 977346d

Browse files
Merge pull request #1583 from json-api-dotnet/use-disallownull-in-pipeline
Add [DisallowNull] on TId in pipeline parameters
2 parents ae5d0d1 + 3897ebd commit 977346d

26 files changed

+128
-95
lines changed

‎src/Examples/DapperExample/Repositories/DapperRepository.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Data.Common;
2+
using System.Diagnostics.CodeAnalysis;
23
using Dapper;
34
using DapperExample.AtomicOperations;
45
using DapperExample.TranslationToSql;
@@ -177,7 +178,7 @@ public async Task<int> CountAsync(FilterExpression? filter, CancellationToken ca
177178
}
178179

179180
/// <inheritdoc />
180-
public Task<TResource> GetForCreateAsync(Type resourceClrType, TId id, CancellationToken cancellationToken)
181+
public Task<TResource> GetForCreateAsync(Type resourceClrType, [DisallowNull]TId id, CancellationToken cancellationToken)
181182
{
182183
ArgumentGuard.NotNull(resourceClrType);
183184

@@ -355,7 +356,7 @@ await ExecuteInTransactionAsync(async transaction =>
355356
}
356357

357358
/// <inheritdoc />
358-
public async Task DeleteAsync(TResource? resourceFromDatabase, TId id, CancellationToken cancellationToken)
359+
public async Task DeleteAsync(TResource? resourceFromDatabase, [DisallowNull]TId id, CancellationToken cancellationToken)
359360
{
360361
TResource placeholderResource = resourceFromDatabase ?? _resourceFactory.CreateInstance<TResource>();
361362
placeholderResource.Id = id;
@@ -451,7 +452,7 @@ await ExecuteInTransactionAsync(async transaction =>
451452
}
452453

453454
/// <inheritdoc />
454-
public async Task AddToToManyRelationshipAsync(TResource? leftResource, TId leftId, ISet<IIdentifiable> rightResourceIds,
455+
public async Task AddToToManyRelationshipAsync(TResource? leftResource, [DisallowNull]TId leftId, ISet<IIdentifiable> rightResourceIds,
455456
CancellationToken cancellationToken)
456457
{
457458
ArgumentGuard.NotNull(rightResourceIds);

‎src/Examples/NoEntityFrameworkExample/Services/InMemoryResourceService.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections;
2+
using System.Diagnostics.CodeAnalysis;
23
using JsonApiDotNetCore.Configuration;
34
using JsonApiDotNetCore.Errors;
45
using JsonApiDotNetCore.Queries;
@@ -114,7 +115,7 @@ private bool SetPrimaryTotalCountIsZero()
114115
}
115116

116117
/// <inheritdoc />
117-
public Task<TResource> GetAsync(TId id, CancellationToken cancellationToken)
118+
public Task<TResource> GetAsync([DisallowNull]TId id, CancellationToken cancellationToken)
118119
{
119120
QueryLayer queryLayer = _queryLayerComposer.ComposeForGetById(id, _resourceType, TopFieldSelection.PreserveExisting);
120121

@@ -124,14 +125,14 @@ public Task<TResource> GetAsync(TId id, CancellationToken cancellationToken)
124125

125126
if (resource == null)
126127
{
127-
throw new ResourceNotFoundException(id!.ToString()!, _resourceType.PublicName);
128+
throw new ResourceNotFoundException(id.ToString()!, _resourceType.PublicName);
128129
}
129130

130131
return Task.FromResult(resource);
131132
}
132133

133134
/// <inheritdoc />
134-
public Task<object?> GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken)
135+
public Task<object?> GetSecondaryAsync([DisallowNull]TId id, string relationshipName, CancellationToken cancellationToken)
135136
{
136137
RelationshipAttribute? relationship = _resourceType.FindRelationshipByPublicName(relationshipName);
137138

@@ -151,7 +152,7 @@ public Task<TResource> GetAsync(TId id, CancellationToken cancellationToken)
151152

152153
if (primaryResource == null)
153154
{
154-
throw new ResourceNotFoundException(id!.ToString()!, _resourceType.PublicName);
155+
throw new ResourceNotFoundException(id.ToString()!, _resourceType.PublicName);
155156
}
156157

157158
object? rightValue = relationship.GetValue(primaryResource);
@@ -164,7 +165,7 @@ public Task<TResource> GetAsync(TId id, CancellationToken cancellationToken)
164165
return Task.FromResult(rightValue);
165166
}
166167

167-
private void SetNonPrimaryTotalCount(TId id, RelationshipAttribute relationship)
168+
private void SetNonPrimaryTotalCount([DisallowNull]TId id, RelationshipAttribute relationship)
168169
{
169170
if (_options.IncludeTotalResourceCount && relationship is HasManyAttribute hasManyRelationship)
170171
{
@@ -188,7 +189,7 @@ private void SetNonPrimaryTotalCount(TId id, RelationshipAttribute relationship)
188189
}
189190

190191
/// <inheritdoc />
191-
public Task<object?> GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken)
192+
public Task<object?> GetRelationshipAsync([DisallowNull]TId id, string relationshipName, CancellationToken cancellationToken)
192193
{
193194
return GetSecondaryAsync(id, relationshipName, cancellationToken);
194195
}

‎src/JsonApiDotNetCore/AtomicOperations/Processors/AddToRelationshipProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public AddToRelationshipProcessor(IAddToRelationshipService<TResource, TId> serv
2626
var leftId = (TId)operation.Resource.GetTypedId();
2727
ISet<IIdentifiable> rightResourceIds = operation.GetSecondaryResources();
2828

29-
await _service.AddToToManyRelationshipAsync(leftId, operation.Request.Relationship!.PublicName, rightResourceIds, cancellationToken);
29+
await _service.AddToToManyRelationshipAsync(leftId!, operation.Request.Relationship!.PublicName, rightResourceIds, cancellationToken);
3030

3131
return null;
3232
}

‎src/JsonApiDotNetCore/AtomicOperations/Processors/DeleteProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public DeleteProcessor(IDeleteService<TResource, TId> service)
2424
ArgumentGuard.NotNull(operation);
2525

2626
var id = (TId)operation.Resource.GetTypedId();
27-
await _service.DeleteAsync(id, cancellationToken);
27+
await _service.DeleteAsync(id!, cancellationToken);
2828

2929
return null;
3030
}

‎src/JsonApiDotNetCore/AtomicOperations/Processors/RemoveFromRelationshipProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public RemoveFromRelationshipProcessor(IRemoveFromRelationshipService<TResource,
2626
var leftId = (TId)operation.Resource.GetTypedId();
2727
ISet<IIdentifiable> rightResourceIds = operation.GetSecondaryResources();
2828

29-
await _service.RemoveFromToManyRelationshipAsync(leftId, operation.Request.Relationship!.PublicName, rightResourceIds, cancellationToken);
29+
await _service.RemoveFromToManyRelationshipAsync(leftId!, operation.Request.Relationship!.PublicName, rightResourceIds, cancellationToken);
3030

3131
return null;
3232
}

‎src/JsonApiDotNetCore/AtomicOperations/Processors/SetRelationshipProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public SetRelationshipProcessor(ISetRelationshipService<TResource, TId> service)
2828
var leftId = (TId)operation.Resource.GetTypedId();
2929
object? rightValue = GetRelationshipRightValue(operation);
3030

31-
await _service.SetRelationshipAsync(leftId, operation.Request.Relationship!.PublicName, rightValue, cancellationToken);
31+
await _service.SetRelationshipAsync(leftId!, operation.Request.Relationship!.PublicName, rightValue, cancellationToken);
3232

3333
return null;
3434
}

‎src/JsonApiDotNetCore/AtomicOperations/Processors/UpdateProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public UpdateProcessor(IUpdateService<TResource, TId> service)
2424
ArgumentGuard.NotNull(operation);
2525

2626
var resource = (TResource)operation.Resource;
27-
TResource? updated = await _service.UpdateAsync(resource.Id, resource, cancellationToken);
27+
TResource? updated = await _service.UpdateAsync(resource.Id!, resource, cancellationToken);
2828

2929
return updated == null ? null : operation.WithResource(updated);
3030
}

‎src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using JsonApiDotNetCore.Configuration;
23
using JsonApiDotNetCore.Errors;
34
using JsonApiDotNetCore.Middleware;
@@ -108,7 +109,7 @@ public virtual async Task<IActionResult> GetAsync(CancellationToken cancellation
108109
/// GET /articles/1 HTTP/1.1
109110
/// ]]></code>
110111
/// </summary>
111-
public virtual async Task<IActionResult> GetAsync(TId id, CancellationToken cancellationToken)
112+
public virtual async Task<IActionResult> GetAsync([DisallowNull]TId id, CancellationToken cancellationToken)
112113
{
113114
_traceWriter.LogMethodStart(new
114115
{
@@ -133,7 +134,7 @@ public virtual async Task<IActionResult> GetAsync(TId id, CancellationToken canc
133134
/// GET /articles/1/revisions HTTP/1.1
134135
/// ]]></code>
135136
/// </summary>
136-
public virtual async Task<IActionResult> GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken)
137+
public virtual async Task<IActionResult> GetSecondaryAsync([DisallowNull]TId id, string relationshipName, CancellationToken cancellationToken)
137138
{
138139
_traceWriter.LogMethodStart(new
139140
{
@@ -162,7 +163,7 @@ public virtual async Task<IActionResult> GetSecondaryAsync(TId id, string relati
162163
/// GET /articles/1/relationships/revisions HTTP/1.1
163164
/// ]]></code>
164165
/// </summary>
165-
public virtual async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken)
166+
public virtual async Task<IActionResult> GetRelationshipAsync([DisallowNull]TId id, string relationshipName, CancellationToken cancellationToken)
166167
{
167168
_traceWriter.LogMethodStart(new
168169
{
@@ -246,8 +247,8 @@ private string GetLocationUrl(string resourceId)
246247
/// <param name="cancellationToken">
247248
/// Propagates notification that request handling should be canceled.
248249
/// </param>
249-
public virtual async Task<IActionResult> PostRelationshipAsync(TId id, string relationshipName,[FromBody]ISet<IIdentifiable>rightResourceIds,
250-
CancellationToken cancellationToken)
250+
public virtual async Task<IActionResult> PostRelationshipAsync([DisallowNull]TId id, string relationshipName,
251+
[FromBody]ISet<IIdentifiable>rightResourceIds,CancellationToken cancellationToken)
251252
{
252253
_traceWriter.LogMethodStart(new
253254
{
@@ -275,7 +276,7 @@ public virtual async Task<IActionResult> PostRelationshipAsync(TId id, string re
275276
/// PATCH /articles/1 HTTP/1.1
276277
/// ]]></code>
277278
/// </summary>
278-
public virtual async Task<IActionResult> PatchAsync(TId id, [FromBody] TResource resource, CancellationToken cancellationToken)
279+
public virtual async Task<IActionResult> PatchAsync([DisallowNull]TId id, [FromBody] TResource resource, CancellationToken cancellationToken)
279280
{
280281
_traceWriter.LogMethodStart(new
281282
{
@@ -321,7 +322,7 @@ public virtual async Task<IActionResult> PatchAsync(TId id, [FromBody] TResource
321322
/// <param name="cancellationToken">
322323
/// Propagates notification that request handling should be canceled.
323324
/// </param>
324-
public virtual async Task<IActionResult> PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object? rightValue,
325+
public virtual async Task<IActionResult> PatchRelationshipAsync([DisallowNull]TId id, string relationshipName, [FromBody] object? rightValue,
325326
CancellationToken cancellationToken)
326327
{
327328
_traceWriter.LogMethodStart(new
@@ -348,7 +349,7 @@ public virtual async Task<IActionResult> PatchRelationshipAsync(TId id, string r
348349
/// DELETE /articles/1 HTTP/1.1
349350
/// ]]></code>
350351
/// </summary>
351-
public virtual async Task<IActionResult> DeleteAsync(TId id, CancellationToken cancellationToken)
352+
public virtual async Task<IActionResult> DeleteAsync([DisallowNull]TId id, CancellationToken cancellationToken)
352353
{
353354
_traceWriter.LogMethodStart(new
354355
{
@@ -382,8 +383,8 @@ public virtual async Task<IActionResult> DeleteAsync(TId id, CancellationToken c
382383
/// <param name="cancellationToken">
383384
/// Propagates notification that request handling should be canceled.
384385
/// </param>
385-
public virtual async Task<IActionResult> DeleteRelationshipAsync(TId id, string relationshipName,[FromBody]ISet<IIdentifiable>rightResourceIds,
386-
CancellationToken cancellationToken)
386+
public virtual async Task<IActionResult> DeleteRelationshipAsync([DisallowNull]TId id, string relationshipName,
387+
[FromBody]ISet<IIdentifiable>rightResourceIds,CancellationToken cancellationToken)
387388
{
388389
_traceWriter.LogMethodStart(new
389390
{

‎src/JsonApiDotNetCore/Controllers/JsonApiController.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel.DataAnnotations;
2+
using System.Diagnostics.CodeAnalysis;
23
using JsonApiDotNetCore.Configuration;
34
using JsonApiDotNetCore.Resources;
45
using JsonApiDotNetCore.Services;
@@ -50,23 +51,25 @@ public override async Task<IActionResult> GetAsync(CancellationToken cancellatio
5051
/// <inheritdoc />
5152
[HttpGet("{id}")]
5253
[HttpHead("{id}")]
53-
public override async Task<IActionResult> GetAsync([Required] TId id, CancellationToken cancellationToken)
54+
public override async Task<IActionResult> GetAsync([Required] [DisallowNull]TId id, CancellationToken cancellationToken)
5455
{
5556
return await base.GetAsync(id, cancellationToken);
5657
}
5758

5859
/// <inheritdoc />
5960
[HttpGet("{id}/{relationshipName}")]
6061
[HttpHead("{id}/{relationshipName}")]
61-
public override async Task<IActionResult> GetSecondaryAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
62+
public override async Task<IActionResult> GetSecondaryAsync([Required] [DisallowNull] TId id, [Required] string relationshipName,
63+
CancellationToken cancellationToken)
6264
{
6365
return await base.GetSecondaryAsync(id, relationshipName, cancellationToken);
6466
}
6567

6668
/// <inheritdoc />
6769
[HttpGet("{id}/relationships/{relationshipName}")]
6870
[HttpHead("{id}/relationships/{relationshipName}")]
69-
public override async Task<IActionResult> GetRelationshipAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
71+
public override async Task<IActionResult> GetRelationshipAsync([Required] [DisallowNull] TId id, [Required] string relationshipName,
72+
CancellationToken cancellationToken)
7073
{
7174
return await base.GetRelationshipAsync(id, relationshipName, cancellationToken);
7275
}
@@ -80,38 +83,38 @@ public override async Task<IActionResult> PostAsync([Required] TResource resourc
8083

8184
/// <inheritdoc />
8285
[HttpPost("{id}/relationships/{relationshipName}")]
83-
public override async Task<IActionResult> PostRelationshipAsync([Required] TId id, [Required] string relationshipName,
86+
public override async Task<IActionResult> PostRelationshipAsync([Required] [DisallowNull]TId id, [Required] string relationshipName,
8487
[Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
8588
{
8689
return await base.PostRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken);
8790
}
8891

8992
/// <inheritdoc />
9093
[HttpPatch("{id}")]
91-
public override async Task<IActionResult> PatchAsync([Required] TId id, [Required] TResource resource, CancellationToken cancellationToken)
94+
public override async Task<IActionResult> PatchAsync([Required] [DisallowNull]TId id, [Required] TResource resource, CancellationToken cancellationToken)
9295
{
9396
return await base.PatchAsync(id, resource, cancellationToken);
9497
}
9598

9699
/// <inheritdoc />
97100
[HttpPatch("{id}/relationships/{relationshipName}")]
98101
// Parameter `[Required] object? rightValue` makes Swashbuckle generate the OpenAPI request body as required. We don't actually validate ModelState, so it doesn't hurt.
99-
public override async Task<IActionResult> PatchRelationshipAsync([Required] TId id, [Required] string relationshipName,[Required]object?rightValue,
100-
CancellationToken cancellationToken)
102+
public override async Task<IActionResult> PatchRelationshipAsync([Required] [DisallowNull]TId id, [Required] string relationshipName,
103+
[Required]object?rightValue,CancellationToken cancellationToken)
101104
{
102105
return await base.PatchRelationshipAsync(id, relationshipName, rightValue, cancellationToken);
103106
}
104107

105108
/// <inheritdoc />
106109
[HttpDelete("{id}")]
107-
public override async Task<IActionResult> DeleteAsync([Required] TId id, CancellationToken cancellationToken)
110+
public override async Task<IActionResult> DeleteAsync([Required] [DisallowNull]TId id, CancellationToken cancellationToken)
108111
{
109112
return await base.DeleteAsync(id, cancellationToken);
110113
}
111114

112115
/// <inheritdoc />
113116
[HttpDelete("{id}/relationships/{relationshipName}")]
114-
public override async Task<IActionResult> DeleteRelationshipAsync([Required] TId id, [Required] string relationshipName,
117+
public override async Task<IActionResult> DeleteRelationshipAsync([Required] [DisallowNull]TId id, [Required] string relationshipName,
115118
[Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
116119
{
117120
return await base.DeleteRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken);

‎src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using JsonApiDotNetCore.Configuration;
23
using JsonApiDotNetCore.Queries.Expressions;
34
using JsonApiDotNetCore.Resources;
@@ -18,7 +19,7 @@ public interface IQueryLayerComposer
1819
/// <summary>
1920
/// Builds a filter from constraints, used to determine total resource count on a secondary collection endpoint.
2021
/// </summary>
21-
FilterExpression? GetSecondaryFilterFromConstraints<TId>(TId primaryId, HasManyAttribute hasManyRelationship);
22+
FilterExpression? GetSecondaryFilterFromConstraints<TId>([DisallowNull]TId primaryId, HasManyAttribute hasManyRelationship);
2223

2324
/// <summary>
2425
/// Collects constraints and builds a <see cref="QueryLayer" /> out of them, used to retrieve the actual resources.
@@ -28,7 +29,7 @@ public interface IQueryLayerComposer
2829
/// <summary>
2930
/// Collects constraints and builds a <see cref="QueryLayer" /> out of them, used to retrieve one resource.
3031
/// </summary>
31-
QueryLayer ComposeForGetById<TId>(TId id, ResourceType primaryResourceType, TopFieldSelection fieldSelection);
32+
QueryLayer ComposeForGetById<TId>([DisallowNull]TId id, ResourceType primaryResourceType, TopFieldSelection fieldSelection);
3233

3334
/// <summary>
3435
/// Collects constraints and builds the secondary layer for a relationship endpoint.
@@ -38,14 +39,14 @@ public interface IQueryLayerComposer
3839
/// <summary>
3940
/// Wraps a layer for a secondary endpoint into a primary layer, rewriting top-level includes.
4041
/// </summary>
41-
QueryLayer WrapLayerForSecondaryEndpoint<TId>(QueryLayer secondaryLayer, ResourceType primaryResourceType, TId primaryId,
42+
QueryLayer WrapLayerForSecondaryEndpoint<TId>(QueryLayer secondaryLayer, ResourceType primaryResourceType, [DisallowNull]TId primaryId,
4243
RelationshipAttribute relationship);
4344

4445
/// <summary>
4546
/// Builds a query that retrieves the primary resource, including all of its attributes and all targeted relationships, during a create/update/delete
4647
/// request.
4748
/// </summary>
48-
QueryLayer ComposeForUpdate<TId>(TId id, ResourceType primaryResourceType);
49+
QueryLayer ComposeForUpdate<TId>([DisallowNull]TId id, ResourceType primaryResourceType);
4950

5051
/// <summary>
5152
/// Builds a query for each targeted relationship with a filter to match on its right resource IDs.
@@ -60,5 +61,5 @@ QueryLayer WrapLayerForSecondaryEndpoint<TId>(QueryLayer secondaryLayer, Resourc
6061
/// <summary>
6162
/// Builds a query for a to-many relationship with a filter to match on its left and right resource IDs.
6263
/// </summary>
63-
QueryLayer ComposeForHasMany<TId>(HasManyAttribute hasManyRelationship, TId leftId, ICollection<IIdentifiable> rightResourceIds);
64+
QueryLayer ComposeForHasMany<TId>(HasManyAttribute hasManyRelationship, [DisallowNull]TId leftId, ICollection<IIdentifiable> rightResourceIds);
6465
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /