Hi @Shamus Schubert
First, JSON Patch support in ASP.NET Core web API is based on Newtonsoft.Json
and requires the Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet package. To enable JSON Patch support, we need to install the Microsoft.AspNetCore.Mvc.NewtonsoftJson
NuGet package and call the NewtonsoftJson service. More detail information, see JsonPatch in ASP.NET Core web API.
Second, in Asp.net core Minimal API, the body binding source uses System.Text.Json for deserialization. It is not possible to change this default. So, we can't use the AddNewtonsoftJon()
method like in ASP.NET Core web API application. More detail information, see Configure JSON deserialization options for body binding.
'Failed to read parameter "JsonPatchDocument patchDocument" from the request body as JSON'
and
'The JSON value could not be converted to Microsoft.AspNetCore.JsonPatch.JsonPatchDocument'.
So, to solve the above issue, you can try to read the request body as string first, then use the Newtonsoft.Json.JsonConvert.DeserializeObject
method to convert the json string to JsonPatchDocument, code like this:
app.MapPatch("/JsonPatchForDynamic/{id}", async (HttpContext context, string id ) =>
{
if (!context.Request.HasJsonContentType())
{
throw new BadHttpRequestException(
"Request content type was not a recognized JSON content type.",
StatusCodes.Status415UnsupportedMediaType);
}
using var sr = new StreamReader(context.Request.Body);
var str = await sr.ReadToEndAsync();
var result = JsonConvert.DeserializeObject<JsonPatchDocument>(str);
return result;
});
Besides, you can also create a wrappers and use the Custom Binding method to bind the value, code like this:
//using Newtonsoft.Json;
//using System.Reflection;
public class Wrapper<TModel>
{
public Wrapper(TModel? value)
{
Value = value;
}
public TModel? Value { get; }
public static async ValueTask<Wrapper<TModel>?> BindAsync(HttpContext context, ParameterInfo parameter)
{
if (!context.Request.HasJsonContentType())
{
throw new BadHttpRequestException(
"Request content type was not a recognized JSON content type.",
StatusCodes.Status415UnsupportedMediaType);
}
using var sr = new StreamReader(context.Request.Body);
var str = await sr.ReadToEndAsync();
return new Wrapper<TModel>(JsonConvert.DeserializeObject<TModel>(str));
}
}
and:
app.MapPatch("/JsonPatchForDynamic2/{id}", async (string id, Wrapper<JsonPatchDocument> po) =>
{
var patchdocument = po.Value;
return patchdocument;
});
The result as below:
Update:
If you want to use Swagger to transfer the JSON string, you can use the JsonElement
parameter, then after getting the Json string, use the JsonConvert.DeserializeObject
method to convert the json string to JsonPatchDocument
. Code like this:
app.MapPatch("/JsonPatchForDynamic3/{id}", async (string id, [FromBody] JsonElement jsonElement) =>
{
var json = jsonElement.GetRawText();
var doc = JsonConvert.DeserializeObject<JsonPatchDocument>(json);
return Results.Ok(doc);
}).WithOpenApi();
The output as below:
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion