Skip to content

Commit 4c08402

Browse files
Copilotcaptainsafia
andcommitted
Implement IEndpointParameterMetadataProvider for JsonPatchDocument
Co-authored-by: captainsafia <[email protected]>
1 parent a913c6a commit 4c08402

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

src/Features/JsonPatch.SystemTextJson/src/JsonPatchDocument.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Reflection;
67
using System.Text.Json;
78
using System.Text.Json.Serialization;
9+
using Microsoft.AspNetCore.Builder;
10+
using Microsoft.AspNetCore.Http.Metadata;
811
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters;
912
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Converters;
1013
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Exceptions;
@@ -18,7 +21,7 @@ namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson;
1821
// documents for cases where there's no class/DTO to work on. Typical use case: backend not built in
1922
// .NET or architecture doesn't contain a shared DTO layer.
2023
[JsonConverter(typeof(JsonPatchDocumentConverter))]
21-
public class JsonPatchDocument : IJsonPatchDocument
24+
public class JsonPatchDocument : IJsonPatchDocument, IEndpointParameterMetadataProvider
2225
{
2326
public List<Operation> Operations { get; private set; }
2427

@@ -218,4 +221,17 @@ IList<Operation> IJsonPatchDocument.GetOperations()
218221

219222
return allOps;
220223
}
224+
225+
/// <summary>
226+
/// Populates metadata for the related <see cref="Endpoint"/> when this type is used as a parameter.
227+
/// </summary>
228+
/// <param name="parameter">The <see cref="ParameterInfo"/> for the endpoint parameter.</param>
229+
/// <param name="builder">The <see cref="EndpointBuilder"/> for the endpoint being constructed.</param>
230+
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
231+
{
232+
ArgumentNullException.ThrowIfNull(parameter);
233+
ArgumentNullException.ThrowIfNull(builder);
234+
235+
builder.Metadata.Add(new AcceptsMetadata(new[] { "application/json-patch+json" }, parameter.ParameterType));
236+
}
221237
}

src/Features/JsonPatch.SystemTextJson/src/JsonPatchDocumentOfT.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using System.Reflection;
1010
using System.Text.Json;
1111
using System.Text.Json.Serialization;
12+
using Microsoft.AspNetCore.Builder;
13+
using Microsoft.AspNetCore.Http.Metadata;
1214
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Adapters;
1315
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Converters;
1416
using Microsoft.AspNetCore.JsonPatch.SystemTextJson.Exceptions;
@@ -23,7 +25,7 @@ namespace Microsoft.AspNetCore.JsonPatch.SystemTextJson;
2325
// including type data in the JsonPatchDocument serialized as JSON (to allow for correct deserialization) - that's
2426
// not according to RFC 6902, and would thus break cross-platform compatibility.
2527
[JsonConverter(typeof(JsonPatchDocumentConverterFactory))]
26-
public class JsonPatchDocument<TModel> : IJsonPatchDocument where TModel : class
28+
public class JsonPatchDocument<TModel> : IJsonPatchDocument, IEndpointParameterMetadataProvider where TModel : class
2729
{
2830
public List<Operation<TModel>> Operations { get; private set; }
2931

@@ -657,6 +659,19 @@ IList<Operation> IJsonPatchDocument.GetOperations()
657659
return allOps;
658660
}
659661

662+
/// <summary>
663+
/// Populates metadata for the related <see cref="Endpoint"/> when this type is used as a parameter.
664+
/// </summary>
665+
/// <param name="parameter">The <see cref="ParameterInfo"/> for the endpoint parameter.</param>
666+
/// <param name="builder">The <see cref="EndpointBuilder"/> for the endpoint being constructed.</param>
667+
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
668+
{
669+
ArgumentNullException.ThrowIfNull(parameter);
670+
ArgumentNullException.ThrowIfNull(builder);
671+
672+
builder.Metadata.Add(new AcceptsMetadata(new[] { "application/json-patch+json" }, parameter.ParameterType));
673+
}
674+
660675
// Internal for testing
661676
internal string GetPath<TProp>(Expression<Func<TModel, TProp>> expr, string position)
662677
{

src/Features/JsonPatch/src/JsonPatchDocument.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Reflection;
7+
using Microsoft.AspNetCore.Builder;
8+
using Microsoft.AspNetCore.Http.Metadata;
69
using Microsoft.AspNetCore.JsonPatch.Adapters;
710
using Microsoft.AspNetCore.JsonPatch.Converters;
811
using Microsoft.AspNetCore.JsonPatch.Exceptions;
@@ -18,7 +21,7 @@ namespace Microsoft.AspNetCore.JsonPatch;
1821
// documents for cases where there's no class/DTO to work on. Typical use case: backend not built in
1922
// .NET or architecture doesn't contain a shared DTO layer.
2023
[JsonConverter(typeof(JsonPatchDocumentConverter))]
21-
public class JsonPatchDocument : IJsonPatchDocument
24+
public class JsonPatchDocument : IJsonPatchDocument, IEndpointParameterMetadataProvider
2225
{
2326
public List<Operation> Operations { get; private set; }
2427

@@ -218,4 +221,17 @@ IList<Operation> IJsonPatchDocument.GetOperations()
218221

219222
return allOps;
220223
}
224+
225+
/// <summary>
226+
/// Populates metadata for the related <see cref="Endpoint"/> when this type is used as a parameter.
227+
/// </summary>
228+
/// <param name="parameter">The <see cref="ParameterInfo"/> for the endpoint parameter.</param>
229+
/// <param name="builder">The <see cref="EndpointBuilder"/> for the endpoint being constructed.</param>
230+
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
231+
{
232+
ArgumentNullException.ThrowIfNull(parameter);
233+
ArgumentNullException.ThrowIfNull(builder);
234+
235+
builder.Metadata.Add(new AcceptsMetadata(new[] { "application/json-patch+json" }, parameter.ParameterType));
236+
}
221237
}

src/Features/JsonPatch/src/JsonPatchDocumentOfT.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
using System.Globalization;
77
using System.Linq;
88
using System.Linq.Expressions;
9+
using System.Reflection;
10+
using Microsoft.AspNetCore.Builder;
11+
using Microsoft.AspNetCore.Http.Metadata;
912
using Microsoft.AspNetCore.JsonPatch.Adapters;
1013
using Microsoft.AspNetCore.JsonPatch.Converters;
1114
using Microsoft.AspNetCore.JsonPatch.Exceptions;
@@ -22,7 +25,7 @@ namespace Microsoft.AspNetCore.JsonPatch;
2225
// including type data in the JsonPatchDocument serialized as JSON (to allow for correct deserialization) - that's
2326
// not according to RFC 6902, and would thus break cross-platform compatibility.
2427
[JsonConverter(typeof(TypedJsonPatchDocumentConverter))]
25-
public class JsonPatchDocument<TModel> : IJsonPatchDocument where TModel : class
28+
public class JsonPatchDocument<TModel> : IJsonPatchDocument, IEndpointParameterMetadataProvider where TModel : class
2629
{
2730
public List<Operation<TModel>> Operations { get; private set; }
2831

@@ -656,6 +659,19 @@ IList<Operation> IJsonPatchDocument.GetOperations()
656659
return allOps;
657660
}
658661

662+
/// <summary>
663+
/// Populates metadata for the related <see cref="Endpoint"/> when this type is used as a parameter.
664+
/// </summary>
665+
/// <param name="parameter">The <see cref="ParameterInfo"/> for the endpoint parameter.</param>
666+
/// <param name="builder">The <see cref="EndpointBuilder"/> for the endpoint being constructed.</param>
667+
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
668+
{
669+
ArgumentNullException.ThrowIfNull(parameter);
670+
ArgumentNullException.ThrowIfNull(builder);
671+
672+
builder.Metadata.Add(new AcceptsMetadata(new[] { "application/json-patch+json" }, parameter.ParameterType));
673+
}
674+
659675
// Internal for testing
660676
internal string GetPath<TProp>(Expression<Func<TModel, TProp>> expr, string position)
661677
{

src/OpenApi/sample/Endpoints/MapSchemasEndpoints.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Immutable;
55
using System.ComponentModel;
66
using Microsoft.AspNetCore.Http.HttpResults;
7+
using Microsoft.AspNetCore.JsonPatch.SystemTextJson;
78

89
public static class SchemasEndpointsExtensions
910
{
@@ -36,6 +37,7 @@ public static IEndpointRouteBuilder MapSchemasEndpoints(this IEndpointRouteBuild
3637
schemas.MapPost("/location", (LocationContainer location) => { });
3738
schemas.MapPost("/parent", (ParentObject parent) => Results.Ok(parent));
3839
schemas.MapPost("/child", (ChildObject child) => Results.Ok(child));
40+
schemas.MapPatch("/json-patch", (JsonPatchDocument<ParentObject> patchDoc) => Results.NoContent());
3941

4042
return endpointRouteBuilder;
4143
}

0 commit comments

Comments
 (0)