Skip to content

Commit

Permalink
Merge pull request #1506 from json-api-dotnet/correct-frombody-requir…
Browse files Browse the repository at this point in the history
…ed-changes

Move back [FromBody] and [Required] to derived controllers
  • Loading branch information
bkoelman committed Mar 17, 2024
2 parents 6b9d4b8 + 6bf4a8c commit 7e864a2
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 38 deletions.
24 changes: 11 additions & 13 deletions src/JsonApiDotNetCore/Controllers/BaseJsonApiController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.ComponentModel.DataAnnotations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Errors;
using JsonApiDotNetCore.Middleware;
Expand Down Expand Up @@ -107,7 +106,7 @@ public virtual async Task<IActionResult> GetAsync(CancellationToken cancellation
/// GET /articles/1 HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> GetAsync([Required] TId id, CancellationToken cancellationToken)
public virtual async Task<IActionResult> GetAsync(TId id, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand All @@ -132,7 +131,7 @@ public virtual async Task<IActionResult> GetAsync([Required] TId id, Cancellatio
/// GET /articles/1/revisions HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> GetSecondaryAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
public virtual async Task<IActionResult> GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down Expand Up @@ -161,7 +160,7 @@ public virtual async Task<IActionResult> GetSecondaryAsync([Required] TId id, [R
/// GET /articles/1/relationships/revisions HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> GetRelationshipAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
public virtual async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand All @@ -186,7 +185,7 @@ public virtual async Task<IActionResult> GetRelationshipAsync([Required] TId id,
/// POST /articles HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> PostAsync([FromBody] [Required] TResource resource, CancellationToken cancellationToken)
public virtual async Task<IActionResult> PostAsync(TResource resource, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down Expand Up @@ -236,8 +235,8 @@ public virtual async Task<IActionResult> PostAsync([FromBody] [Required] TResour
/// <param name="cancellationToken">
/// Propagates notification that request handling should be canceled.
/// </param>
public virtual async Task<IActionResult> PostRelationshipAsync([Required] TId id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
public virtual async Task<IActionResult> PostRelationshipAsync(TId id, string relationshipName, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down Expand Up @@ -265,7 +264,7 @@ public virtual async Task<IActionResult> PostRelationshipAsync([Required] TId id
/// PATCH /articles/1 HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> PatchAsync([Required] TId id, [FromBody] [Required] TResource resource, CancellationToken cancellationToken)
public virtual async Task<IActionResult> PatchAsync(TId id, TResource resource, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down Expand Up @@ -311,8 +310,7 @@ public virtual async Task<IActionResult> PatchAsync([Required] TId id, [FromBody
/// <param name="cancellationToken">
/// Propagates notification that request handling should be canceled.
/// </param>
public virtual async Task<IActionResult> PatchRelationshipAsync([Required] TId id, [Required] string relationshipName, [FromBody] object? rightValue,
CancellationToken cancellationToken)
public virtual async Task<IActionResult> PatchRelationshipAsync(TId id, string relationshipName, object? rightValue, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand All @@ -338,7 +336,7 @@ public virtual async Task<IActionResult> PatchRelationshipAsync([Required] TId i
/// DELETE /articles/1 HTTP/1.1
/// ]]></code>
/// </summary>
public virtual async Task<IActionResult> DeleteAsync([Required] TId id, CancellationToken cancellationToken)
public virtual async Task<IActionResult> DeleteAsync(TId id, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down Expand Up @@ -372,8 +370,8 @@ public virtual async Task<IActionResult> DeleteAsync([Required] TId id, Cancella
/// <param name="cancellationToken">
/// Propagates notification that request handling should be canceled.
/// </param>
public virtual async Task<IActionResult> DeleteRelationshipAsync([Required] TId id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
public virtual async Task<IActionResult> DeleteRelationshipAsync(TId id, string relationshipName, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;
using JsonApiDotNetCore.AtomicOperations;
using JsonApiDotNetCore.Configuration;
Expand Down Expand Up @@ -103,8 +102,7 @@ protected BaseJsonApiOperationsController(IJsonApiOptions options, IResourceGrap
/// }
/// ]]></code>
/// </example>
public virtual async Task<IActionResult> PostOperationsAsync([FromBody] [Required] IList<OperationContainer> operations,
CancellationToken cancellationToken)
public virtual async Task<IActionResult> PostOperationsAsync(IList<OperationContainer> operations, CancellationToken cancellationToken)
{
_traceWriter.LogMethodStart(new
{
Expand Down
24 changes: 13 additions & 11 deletions src/JsonApiDotNetCore/Controllers/JsonApiController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.ComponentModel.DataAnnotations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Services;
Expand Down Expand Up @@ -49,68 +50,69 @@ public override Task<IActionResult> GetAsync(CancellationToken cancellationToken
/// <inheritdoc />
[HttpGet("{id}")]
[HttpHead("{id}")]
public override Task<IActionResult> GetAsync(TId id, CancellationToken cancellationToken)
public override Task<IActionResult> GetAsync([Required] TId id, CancellationToken cancellationToken)
{
return base.GetAsync(id, cancellationToken);
}

/// <inheritdoc />
[HttpGet("{id}/{relationshipName}")]
[HttpHead("{id}/{relationshipName}")]
public override Task<IActionResult> GetSecondaryAsync(TId id, string relationshipName, CancellationToken cancellationToken)
public override Task<IActionResult> GetSecondaryAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
{
return base.GetSecondaryAsync(id, relationshipName, cancellationToken);
}

/// <inheritdoc />
[HttpGet("{id}/relationships/{relationshipName}")]
[HttpHead("{id}/relationships/{relationshipName}")]
public override Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken)
public override Task<IActionResult> GetRelationshipAsync([Required] TId id, [Required] string relationshipName, CancellationToken cancellationToken)
{
return base.GetRelationshipAsync(id, relationshipName, cancellationToken);
}

/// <inheritdoc />
[HttpPost]
public override Task<IActionResult> PostAsync(TResource resource, CancellationToken cancellationToken)
public override Task<IActionResult> PostAsync([FromBody] [Required] TResource resource, CancellationToken cancellationToken)
{
return base.PostAsync(resource, cancellationToken);
}

/// <inheritdoc />
[HttpPost("{id}/relationships/{relationshipName}")]
public override Task<IActionResult> PostRelationshipAsync(TId id, string relationshipName, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
public override Task<IActionResult> PostRelationshipAsync([Required] TId id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
{
return base.PostRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken);
}

/// <inheritdoc />
[HttpPatch("{id}")]
public override Task<IActionResult> PatchAsync(TId id, TResource resource, CancellationToken cancellationToken)
public override Task<IActionResult> PatchAsync([Required] TId id, [FromBody] [Required] TResource resource, CancellationToken cancellationToken)
{
return base.PatchAsync(id, resource, cancellationToken);
}

/// <inheritdoc />
[HttpPatch("{id}/relationships/{relationshipName}")]
public override Task<IActionResult> PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object? rightValue,
// Parameter `[Required] object? rightValue` makes Swashbuckle generate the OpenAPI request body as required. We don't actually validate ModelState, so it doesn't hurt.
public override Task<IActionResult> PatchRelationshipAsync([Required] TId id, [Required] string relationshipName, [FromBody] [Required] object? rightValue,
CancellationToken cancellationToken)
{
return base.PatchRelationshipAsync(id, relationshipName, rightValue, cancellationToken);
}

/// <inheritdoc />
[HttpDelete("{id}")]
public override Task<IActionResult> DeleteAsync(TId id, CancellationToken cancellationToken)
public override Task<IActionResult> DeleteAsync([Required] TId id, CancellationToken cancellationToken)
{
return base.DeleteAsync(id, cancellationToken);
}

/// <inheritdoc />
[HttpDelete("{id}/relationships/{relationshipName}")]
public override Task<IActionResult> DeleteRelationshipAsync(TId id, string relationshipName, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
public override Task<IActionResult> DeleteRelationshipAsync([Required] TId id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
{
return base.DeleteRelationshipAsync(id, relationshipName, rightResourceIds, cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.ComponentModel.DataAnnotations;
using JsonApiDotNetCore.AtomicOperations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
Expand All @@ -17,7 +18,7 @@ public abstract class JsonApiOperationsController(
{
/// <inheritdoc />
[HttpPost]
public override Task<IActionResult> PostOperationsAsync(IList<OperationContainer> operations, CancellationToken cancellationToken)
public override Task<IActionResult> PostOperationsAsync([FromBody] [Required] IList<OperationContainer> operations, CancellationToken cancellationToken)
{
return base.PostOperationsAsync(operations, cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ public override Task<IActionResult> GetAsync(CancellationToken cancellationToken
}

[HttpGet("{id}")]
public Task<IActionResult> GetAsync(string id, CancellationToken cancellationToken)
public Task<IActionResult> GetAsync([Required] string id, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.GetAsync(idValue, cancellationToken);
}

[HttpGet("{id}/{relationshipName}")]
public Task<IActionResult> GetSecondaryAsync(string id, string relationshipName, CancellationToken cancellationToken)
public Task<IActionResult> GetSecondaryAsync([Required] string id, [Required] string relationshipName, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.GetSecondaryAsync(idValue, relationshipName, cancellationToken);
}

[HttpGet("{id}/relationships/{relationshipName}")]
public Task<IActionResult> GetRelationshipAsync(string id, string relationshipName, CancellationToken cancellationToken)
public Task<IActionResult> GetRelationshipAsync([Required] string id, [Required] string relationshipName, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.GetRelationshipAsync(idValue, relationshipName, cancellationToken);
Expand All @@ -49,37 +49,39 @@ public override Task<IActionResult> PostAsync([FromBody] [Required] TResource re
}

[HttpPost("{id}/relationships/{relationshipName}")]
public Task<IActionResult> PostRelationshipAsync(string id, string relationshipName, [FromBody] [Required] ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
public Task<IActionResult> PostRelationshipAsync([Required] string id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.PostRelationshipAsync(idValue, relationshipName, rightResourceIds, cancellationToken);
}

[HttpPatch("{id}")]
public Task<IActionResult> PatchAsync(string id, [FromBody] [Required] TResource resource, CancellationToken cancellationToken)
public Task<IActionResult> PatchAsync([Required] string id, [FromBody] [Required] TResource resource, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.PatchAsync(idValue, resource, cancellationToken);
}

[HttpPatch("{id}/relationships/{relationshipName}")]
public Task<IActionResult> PatchRelationshipAsync(string id, string relationshipName, [FromBody] object? rightValue, CancellationToken cancellationToken)
// Parameter `[Required] object? rightValue` makes Swashbuckle generate the OpenAPI request body as required. We don't actually validate ModelState, so it doesn't hurt.
public Task<IActionResult> PatchRelationshipAsync([Required] string id, [Required] string relationshipName, [FromBody] [Required] object? rightValue,
CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.PatchRelationshipAsync(idValue, relationshipName, rightValue, cancellationToken);
}

[HttpDelete("{id}")]
public Task<IActionResult> DeleteAsync(string id, CancellationToken cancellationToken)
public Task<IActionResult> DeleteAsync([Required] string id, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.DeleteAsync(idValue, cancellationToken);
}

[HttpDelete("{id}/relationships/{relationshipName}")]
public Task<IActionResult> DeleteRelationshipAsync(string id, string relationshipName, [FromBody] [Required] ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
public Task<IActionResult> DeleteRelationshipAsync([Required] string id, [Required] string relationshipName,
[FromBody] [Required] ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
{
int idValue = _codec.Decode(id);
return base.DeleteRelationshipAsync(idValue, relationshipName, rightResourceIds, cancellationToken);
Expand Down

0 comments on commit 7e864a2

Please sign in to comment.