Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement JsonPatch in .NET Core 3.0 Preview 9 correctly?

I am trying to implement JsonPatch on .NET Core 3.0 Preview 9 web api.

The model:

public class TestPatch
{
    public string TestPath { get; set; }
}

The web api endpoint:

[HttpPatch()]
public async Task<IActionResult> Update([FromBody] JsonPatchDocument<TestPatch> patch)
{
   ...........
   return Ok();
}

The JSON payload:

[
    {
        "op" : "replace",
        "path" : "/testPath",
        "value" : "new value"
    }
]

Using PATCH via Postman, I got this error:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|492c592-4f7de4d16a32b942.",
"errors": {
    "$": [
        "The JSON value could not be converted to Microsoft.AspNetCore.JsonPatch.JsonPatchDocument`1[Test.Models.TestPatch]. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
    ]
}
}

Here's the complete request/response from Postman

PATCH /api/helptemplates HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.16.3
Accept: */*
Cache-Control: no-cache
Postman-Token: a41813ea-14db-4664-98fb-ee30511707bc
Host: localhost:5002
Accept-Encoding: gzip, deflate
Content-Length: 77
Connection: keep-alive
[
{
"op" : "replace",
"path" : "/testPath",
"value" : "new value"
}
]
HTTP/1.1 400 Bad Request
Date: Thu, 12 Sep 2019 21:13:08 GMT
Content-Type: application/problem+json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|492c593-4f7de4d16a32b942.","errors":{"$":["The JSON value could not be converted to Microsoft.AspNetCore.JsonPatch.JsonPatchDocument`1[Test.Models.TestPatch]. Path: $ | LineNumber: 0 | BytePositionInLine: 1."]}}

JsonPatch Reference:

<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.0.0-preview9.19424.4" />

What is wrong with my code?

Thanks.

like image 699
Ronald Ramos Avatar asked Sep 12 '19 21:09

Ronald Ramos


1 Answers

Support for JsonPatch is enabled using the Microsoft.AspNetCore.Mvc.NewtonsoftJson package. To enable this feature, apps must:

  • Install the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package.

  • Update the project's Startup.ConfigureServices method to include a call to AddNewtonsoftJson

services
    .AddControllers()
    .AddNewtonsoftJson();

AddNewtonsoftJson is compatible with the MVC service registration methods:

  • AddRazorPages
  • AddControllersWithViews
  • AddControllers

But if you are using asp.net core 3.x, then

AddNewtonsoftJson replaces the System.Text.Json based input and output formatters used for formatting all JSON content. To add support for JsonPatch using Newtonsoft.Json, while leaving the other formatters unchanged, update the project's Startup.ConfigureServices as follows:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
    {
        options.InputFormatters.Insert(0, GetJsonPatchInputFormatter());
    });
}

private static NewtonsoftJsonPatchInputFormatter GetJsonPatchInputFormatter()
{
    var builder = new ServiceCollection()
        .AddLogging()
        .AddMvc()
        .AddNewtonsoftJson()
        .Services.BuildServiceProvider();

    return builder
        .GetRequiredService<IOptions<MvcOptions>>()
        .Value
        .InputFormatters
        .OfType<NewtonsoftJsonPatchInputFormatter>()
        .First();
}

The preceding code requires a reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson and the following using statements:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Linq;

A brief explanation and documentation for the above can be found in this link

like image 170
fingers10 Avatar answered Sep 29 '22 16:09

fingers10