Reputation: 5480
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.
Upvotes: 7
Views: 6793
Reputation: 21
For those using .NET Core 6.0:
Add the Nuget package: Microsoft.AspNetCore.Mvc.NewtonsoftJson to your project
Then add this using statement to your Program.cs:
using Newtonsoft.Json.Serialization;
Finally add this code to your Program.cs:
builder.Services.AddControllers(options =>
{
options.ReturnHttpNotAcceptable = true;
}).AddXmlDataContractSerializerFormatters().AddNewtonsoftJson();
Upvotes: -1
Reputation: 7977
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
Upvotes: 12
Reputation: 1450
This answer is for 3.1, but I think it applies to 3.0 as well.... The default json parser in asp.net core 3.x isn't as complete as NewtonsoftJson, so use it until Microsoft implements a feature.
Add this nuget package to your project: Microsoft.AspNetCore.Mvc.NewtonsoftJson
Then add this using statement in startup.cs:
using Newtonsoft.Json.Serialization;
... Then change your ConfigureService() to include the NewtonsoftJson formatter in startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(setupAction =>
setupAction.ReturnHttpNotAcceptable = true
).AddXmlDataContractSerializerFormatters().AddNewtonsoftJson(setupAction =>
setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
//...
}
You may also have to add Accept set to application/json to your requests to prevent them returning XML.
Hope this helps.
Upvotes: 6