Ron*_*mos 7 asp.net .net-core asp.net-core-3.0 .net-core-3.0
我正在尝试在 .NET Core 3.0 Preview 9 web api 上实现 JsonPatch。
该模型:
public class TestPatch
{
public string TestPath { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Web API 端点:
[HttpPatch()]
public async Task<IActionResult> Update([FromBody] JsonPatchDocument<TestPatch> patch)
{
...........
return Ok();
}
Run Code Online (Sandbox Code Playgroud)
JSON 有效负载:
[
{
"op" : "replace",
"path" : "/testPath",
"value" : "new value"
}
]
Run Code Online (Sandbox Code Playgroud)
通过 Postman 使用 PATCH,我收到此错误:
{
"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."
]
}
}
Run Code Online (Sandbox Code Playgroud)
这是来自 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."]}}
Run Code Online (Sandbox Code Playgroud)
JsonPatch 参考:
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.0.0-preview9.19424.4" />
Run Code Online (Sandbox Code Playgroud)
我的代码有什么问题?
谢谢。
JsonPatch使用Microsoft.AspNetCore.Mvc.NewtonsoftJson包启用对 的支持。要启用此功能,应用程序必须:
安装Microsoft.AspNetCore.Mvc.NewtonsoftJsonNuGet 包。
更新项目的Startup.ConfigureServices方法以包括对AddNewtonsoftJson
services
.AddControllers()
.AddNewtonsoftJson();
Run Code Online (Sandbox Code Playgroud)
AddNewtonsoftJson 兼容MVC服务注册方式:
AddRazorPages AddControllersWithViews AddControllers但是如果你正在使用asp.net core 3.x,那么
AddNewtonsoftJson替换System.Text.Json用于格式化所有JSON 内容的基于输入和输出的格式化程序。要添加对JsonPatchusing 的支持Newtonsoft.Json,同时保持其他格式化程序不变,请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();
}
Run Code Online (Sandbox Code Playgroud)
前面的代码需要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;
Run Code Online (Sandbox Code Playgroud)
可以在此链接中找到上述内容的简要说明和文档
这个答案适用于 3.1,但我认为它也适用于 3.0...asp.net core 3.x 中的默认 json 解析器并不像 NewtonsoftJson 那样完整,因此请使用它,直到 Microsoft 实现某个功能。
将此 nuget 包添加到您的项目中:Microsoft.AspNetCore.Mvc.NewtonsoftJson
然后在startup.cs中添加以下using语句:
using Newtonsoft.Json.Serialization;
Run Code Online (Sandbox Code Playgroud)
...然后更改您的ConfigureService()以在startup.cs中包含NewtonsoftJson格式化程序:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(setupAction =>
setupAction.ReturnHttpNotAcceptable = true
).AddXmlDataContractSerializerFormatters().AddNewtonsoftJson(setupAction =>
setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
//...
}
Run Code Online (Sandbox Code Playgroud)
您可能还需要将 Accept set 添加到 application/json 到您的请求中,以防止它们返回 XML。
希望这可以帮助。