asp.net 如何在.NET Core 3.0 Preview 9中正确实现JsonPatch?

voase2hg  于 2023-01-03  发布在  .NET
关注(0)|答案(3)|浏览(131)

我正在尝试在. NET Core 3.0 Preview 9 Web API上实现JsonPatch。
模型:

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

Web API终结点:

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

JSON有效负载:

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

使用补丁通过 Postman ,我得到了这个错误:

{
"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."
    ]
}
}

下面是来自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引用:

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

我的代码有什么问题?
谢谢。

zi8p0yeb

zi8p0yeb1#

使用Microsoft.AspNetCore.Mvc.NewtonsoftJson包启用对JsonPatch的支持。要启用此功能,应用必须:

  • 安装Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet软件包。
  • 更新项目的Startup.ConfigureServices方法以包含对AddNewtonsoftJson的调用
services
    .AddControllers()
    .AddNewtonsoftJson();

AddNewtonsoftJson兼容MVC服务注册方式:

  • AddRazorPages
  • AddControllersWithViews
  • AddControllers

但如果您使用的是**asp.net core 3.x,则
AddNewtonsoftJson替换基于System.Text.Json的输入和输出格式化程序,用于格式化
所有**JSON内容。要使用Newtonsoft.Json添加对JsonPatch的支持,同时保持其他格式化程序不变,请按如下所示更新项目的Startup.ConfigureServices

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();
}

上述代码需要对Microsoft.AspNetCore.Mvc.NewtonsoftJson的引用和以下using语句:

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;

可在此链接中找到上述内容的简要说明和文档

fnx2tebb

fnx2tebb2#

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.
将此nuget包添加到您的项目:Microsoft.AspNetCore.Mvc.NewtonsoftJson
然后在startup.cs中添加以下using语句:

using Newtonsoft.Json.Serialization;

...然后更改ConfigureService()以在startup. cs中包含NewtonsoftJson格式化程序:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(setupAction =>
    setupAction.ReturnHttpNotAcceptable = true
   ).AddXmlDataContractSerializerFormatters().AddNewtonsoftJson(setupAction =>
   setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
   //...
}

您可能还必须将Accept set to application/json添加到请求中,以防止它们返回XML。
希望这个有用。

n9vozmp4

n9vozmp43#

对于使用.NET Core 6.0的用户:
添加Nuget软件包:添加到您的项目
然后将此using语句添加到您的Program.cs中:

using Newtonsoft.Json.Serialization;

最后将此代码添加到您的Program.cs:

builder.Services.AddControllers(options =>
{
    options.ReturnHttpNotAcceptable = true;
}).AddXmlDataContractSerializerFormatters().AddNewtonsoftJson();

相关问题