我无法让Spring Data REST接受JSON-PATCH内容体,我做错了什么?
简单域名:
@Document
public class DomainA {
@Id private String id;
private String atext;
public String getAtext(){ return atext;}
public void setAtext(String str){ atext = str;}
}
Run Code Online (Sandbox Code Playgroud)
由MondoDB回购支持:
@RepositoryRestResource
public interface DomainARepository extends MongoRepository<DomainA, String> {}
Run Code Online (Sandbox Code Playgroud)
我想要JSON-PATCH这样,如下:
curl -X PATCH -H "Authorization: Basic dXNlcjpQVw=="
-H "Content-Type: application/json-patch+json"
-H "Cache-Control: no-cache"
-d '[{"op":"replace", "path":"/atext", "value":"JSON-PATCHed text"}]'
http://localhost:8080/domainAs/550e169209a5cc0df82c95d4
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,我得到一个例外:
org.springframework.http.converter.HttpMessageNotReadableException:
Could not read an object of type class patchex.DomainA from the request!;
nested exception is
org.springframework.http.converter.HttpMessageNotReadableException:
Could not read payload!; …Run Code Online (Sandbox Code Playgroud) 我试图将元素追加到数组。但是我不能确保数组已经存在。因此,如果没有创建它。
此示例有效:
来源json:
{
"data": []
}
Run Code Online (Sandbox Code Playgroud)
补丁文件:
[{
"op":"add",
"path":"/data/-",
"value": "foo"
}]
Run Code Online (Sandbox Code Playgroud)
但是在这种情况下,它不会追加任何内容:
来源json:
{}
Run Code Online (Sandbox Code Playgroud)
我通过先添加一个空数组然后追加来尝试解决方案,但这将始终清除现有条目:
[{
"op":"add",
"path":"/scores",
"value": []
},
{
"op":"add",
"path":"/scores/-",
"value": {
"time":1512545873
}
}]
Run Code Online (Sandbox Code Playgroud)
我是否错过了某些东西,或者在规范中没有解决方案?
我在 Microsoft 文档和许多示例中看到他们调用 JsonPatchDocument.ApplyTo(patchObject, ModelState),但我似乎无法让它以这种方式构建。我收到一个构建错误,提示“错误 CS1503 参数 2:无法从‘System.Web.Http.ModelBinding.ModelStateDictionary’转换为‘System.Action’”
我引用了 Microsoft.AspNetCore.JsonPatch v2.2.0,示例代码来自这里:
https://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-2.2
[HttpPatch]
public IActionResult JsonPatchWithModelState(
[FromBody] JsonPatchDocument<Customer> patchDoc)
{
if (patchDoc != null)
{
var customer = CreateCustomer();
patchDoc.ApplyTo(customer, ModelState);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return new ObjectResult(customer);
}
else
{
return BadRequest(ModelState);
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用JsonPatchDocument更新我的实体,如果JSON看起来如下,这很好用
[
{ "op": "replace", "path": "/leadStatus", "value": "2" },
]
Run Code Online (Sandbox Code Playgroud)
当我创建对象时,它会将其转换为Operations节点
var patchDoc = new JsonPatchDocument<LeadTransDetail>();
patchDoc.Replace("leadStatus", statusId);
{
"Operations": [
{
"value": 2,
"path": "/leadStatus",
"op": "replace",
"from": "string"
}
]
}
Run Code Online (Sandbox Code Playgroud)
如果JSON对象看起来像Patch不起作用.我相信我需要使用它来转换它
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new JsonPatchFormatter());
}
Run Code Online (Sandbox Code Playgroud)
这应该解决,问题是我使用.net核心所以不是100%确定在哪里添加 JsonPatchFormatter
我试图找出修补对象集合的最佳方法.我试图改变许多对象的排序顺序,并认为jsonpatch可能是正确的方法.我的对象看起来像:
[
{
"ID": "100",
"FirstName": "John",
"LastName": "Smith",
"Email": "jsmith@test.com",
"SortOrder": 1
},
{
"ID": "125",
"FirstName": "John",
"LastName": "Doe",
"Email": "jdoe@test.com",
"SortOrder": 3
},
{
"ID": "50",
"FirstName": "james",
"LastName": "johnson",
"Email": "jjohnson@test.com",
"SortOrder": 2
},
]
Run Code Online (Sandbox Code Playgroud)
我创建了一个端点,允许补丁请求使用jsonpatch请求更新集合中的多个对象,如下所示:
[
{
"op": "replace",
"path": "/1/SortOrder",
"value": 2
},
{
"op": "replace",
"path": "/0/SortOrder",
"value": 1
},
{
"op": "replace",
"path": "/2/SortOrder",
"value": 3
}
]
Run Code Online (Sandbox Code Playgroud)
我想要做的是使用jsonpatch路径中的ID属性.我目前的对象结构可能吗?它看起来像:
[
{
"op": "replace",
"path": "/125/SortOrder",
"value": 2
},
{
"op": "replace",
"path": …Run Code Online (Sandbox Code Playgroud) 我有两个JSON文件:
JSON 1
{
"title": "This is a title",
"person" : {
"firstName" : "John",
"lastName" : "Doe"
},
"cities":[ "london", "paris" ]
}
Run Code Online (Sandbox Code Playgroud)
JSON 2
{
"title": "This is another title",
"person" : {
"firstName" : "Jane"
},
"cities":[ "colombo" ]
}
Run Code Online (Sandbox Code Playgroud)
我想将#2合并到#1,其中#2覆盖#1,产生以下输出:
{
"title": "This is another title",
"person" : {
"firstName" : "Jane",
"lastName" : "Doe"
},
"cities":[ "colombo" ]
}
Run Code Online (Sandbox Code Playgroud)
我检查了crate json-patch,它做了这个,但它不能编译对稳定的Rust.有可能做类似serde_json和稳定的Rust 这样的东西吗?
我在一所学校的课程和学生之间存在多对多关系。这是我的课程内容:
public class Course
{
public Guid CourseId { get; set; }
public string Name { get; set; }
public ICollection<CourseStudent> Students { get; set; }
}
public class CourseStudent
{
public Guid CourseId { get; set; }
public Guid StudentId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 JsonPatch 来修补我的对象。我正在尝试添加到 的集合中Students,只是添加到集合的末尾:
[
{
"op": "add",
"path": "/Students/-",
"value": [
{
"CourseId": "07264DC9-9FEB-42E2-B1EF-08D58F58C873",
"StudentId": "FB6E6988-4A56-4CA4-86E2-E23090FAD98F"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
但是当我提交这个时,我收到一个例外:
"ClassName": "Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException",
"Message": "值 '[\r\n {\r\n \"CourseId\": \"07264DC9-9FEB-42E2-B1EF-08D58F58C873\",\r\n \"StudentId\": \" …
I'm looking for a way to validate and check the values of the model that is sent to my PATCH method for updating. I haven't found my answer yet.
我已经阅读了 JsonPatch 文档,但没有找到我想要的。
场景:我有一个 RESTful Web API,并且说我有一个名为“users”的资源。假设客户端想要部分更新“用户”资源:(PATCH api/users/{id}),例如,当客户端发送 JsonPatch 文档时,我必须检查是否发送电子邮件进行更新,如果是,我必须检查电子邮件是否重复。那么,我怎么能用下面这样的方法来做到这一点:(我使用 ASP.NET Web API)
[HttpPatch]
[Route("{userId}")]
public HttpResponseMessage UpdateUser(int userId, JsonPatch.JsonPatchDocument<User> patchDocument)
{
// I could do this but before that I wanna validate the proeprties:
patchDocument.ApplyUpdatesTo(dbContext.Users.Single(u => u.Id == userId));
}
Run Code Online (Sandbox Code Playgroud) 我有一个可能包含大量资源的端点。它们以分页列表的形式返回。每个资源都有一个唯一的id、一个rank字段和一些其他数据。从语义上讲,资源是根据其 进行排序的rank。用户应该能够更改该顺序。我正在寻找一个 RESTful 接口来更改rank大型集合中许多资源中的字段。
对一项资源重新排序可能会导致许多资源的字段发生更改rank。例如,考虑将最不重要的资源移动到最重要的位置。许多资源可能需要“降低其级别”。
分页的集合使问题变得更加困难。之前也有过类似的问题,关于一个小集合
该rank字段是整数类型。如果它能产生合理的接口,我可以更改它的类型。
例如:
GET /my-resources?limit=3&marker=234返回:
{
"pagination": {
"prevMarker": 123,
"nextMarker": 345
},
"data": [
{
"id": 12,
"rank": 2,
"otherData": {}
},
{
"id": 35,
"rank": 0,
"otherData": {}
},
{
"id": 67,
"rank": 1,
"otherData": {}
}
]
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用标准 json-patch 请求修改排名字段。例如以下内容:
[
{
"op": "replace",
"path": "/data/0/rank",
"value": 0
}, …Run Code Online (Sandbox Code Playgroud) 我们有一个 .netcore 3.1 ApiController,其端点侦听 PATCH 请求,并定义了一个用于集成/API 测试的测试服务器。
使用 Postman 发送的 PATCH 请求工作得很好,但在 XUnit 测试中通过 HttpClient 发送的请求失败,并显示 415 不支持的媒体类型。
邮递员补丁请求:除了承载令牌和内容类型之外没有特定标头:“application/json”
在测试中,我们使用 WebApplicationFactory 及其 HttpClient 的factory.CreateClient()。
这不应该是 Json 序列化的问题,因为我通过调试器查看了内容,它似乎序列化得很好。
此外,我们的 POST 方法完全开箱即用,使用完全相同的代码(将“PATCH”替换为“POST”等)
期待一些建议。另外,如果您需要更多信息,请告诉我。多谢。
控制器:
[HttpPatch("{id}")]
public async Task<ActionResult<Unit>> Edit(Edit.Command request)
{
return await Mediator.Send(request);
}
Run Code Online (Sandbox Code Playgroud)
命令:
public class Command : IRequest
{
public string Id { get; set; }
public JsonPatchDocument<ObjectDTO> PatchDocument { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
测试:
[InlineData(/* inline data goes here */)]
public async void TestEdit_Ok(/* required parameters for the …Run Code Online (Sandbox Code Playgroud) json-patch ×10
c# ×4
json ×3
asp.net-core ×2
patch ×2
rest ×2
.net-core ×1
api ×1
asp.net ×1
http ×1
rust ×1
serde ×1
serde-json ×1
spring-mvc ×1