[英]C# HTTP PATCH using HTTPClient
I've written a test using Test Server in dot net core 3.1 and I'm trying to do a PATCH request to an endpoint.我已经使用 dot net core 3.1 中的测试服务器编写了一个测试,并且我正在尝试向端点发出 PATCH 请求。 However as I'm new to using PATCH, I'm a bit stuck with how to send the correct object that the endpoint is expecting.但是,由于我是使用 PATCH 的新手,所以我有点不知道如何发送端点期望的正确 object。
[Fact]
public async Task Patch()
{
var operations = new List<Operation>
{
new Operation("replace", "entryId", "'attendance ui", 5)
};
var jsonPatchDocument = new JsonPatchDocument(operations, new DefaultContractResolver());
// Act
var content = new StringContent(JsonConvert.SerializeObject(jsonPatchDocument), Encoding.UTF8, "application/json");
var httpResponse = await HttpClient.PatchAsync($"v1/Entry/1", content);
var actual = await httpResponse.Content.ReadAsStringAsync();
}
[HttpPatch("{entryId}")]
public async Task<ActionResult> Patch(int entryId, [FromBody] JsonPatchDocument<EntryModel> patchDocument)
{
if (patchDocument == null)
{
return BadRequest();
}
var existingEntry = _mapper.Map<EntryModel>(await _entryService.Get(entryId));
patchDocument.ApplyTo(existingEntry);
var entry = _mapper.Map<Entry>(existingEntry);
var updatedEntry = _mapper.Map<Entry>(await _entryService.Update(entryId, entry));
return Ok(await updatedEntry.ModelToPayload());
}
From the example I'm creating a JsonPatchDocument with a list of operations, serializing it to JSON and then doing PatchAsync with HTTP Client with the URL for the endpoint.从示例中,我正在创建一个带有操作列表的 JsonPatchDocument,将其序列化为 JSON,然后使用 HTTP 客户端与端点进行 PatchAsync 与 ZE6B391A8D2C4D45902A23A8B6DZ57。
So my question is what is the shape of the object that I should be Patching and I'm doing this correctly in general?所以我的问题是我应该修补的 object 的形状是什么,并且我通常正确地执行此操作?
I tried sending the EntryModel as shown in the picture below, however patchDocument.Operations has an empty list.我尝试发送如下图所示的 EntryModel,但是 patchDocument.Operations 有一个空列表。
Thanks, Nick谢谢,尼克
I ended up solving my problem by doing several things:我最终通过做几件事来解决我的问题:
services.AddControllers().AddNewtonsoftJson();
如果没有依赖services.AddControllers().AddNewtonsoftJson();
似乎不起作用in Startup.cs.在 Startup.cs 中。 This is from the Nuget package `Microsoft.AspNetCore.Mvc.Newtonsoft.json.这是来自 Nuget package `Microsoft.AspNetCore.Mvc.Newtonsoft.json。var patchDoc = new JsonPatchDocument<EntryModel>().Replace(o => o.EntryTypeId, 5);
这是: var patchDoc = new JsonPatchDocument<EntryModel>().Replace(o => o.EntryTypeId, 5);
var content = new StringContent(JsonConvert.SerializeObject(patchDoc), Encoding.UTF8, "application/json-patch+json");
您需要这种特定的媒体类型: var content = new StringContent(JsonConvert.SerializeObject(patchDoc), Encoding.UTF8, "application/json-patch+json");
Here is the complete code:这是完整的代码:
/// <summary>
/// Verify PUT /Entrys is working and returns updated records
/// </summary>
[Fact]
public async Task Patch()
{
var patchDoc = new JsonPatchDocument<EntryModel>()
.Replace(o => o.EntryTypeId, 5);
var content = new StringContent(JsonConvert.SerializeObject(patchDoc), Encoding.UTF8, "application/json-patch+json");
var httpResponse = await HttpClient.PatchAsync($"v1/Entry/1", content);
var actual = await httpResponse.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, httpResponse.StatusCode);
Assert.True(httpResponse.IsSuccessStatusCode);
}
/// <summary>
/// Endpoint to do partial update
/// </summary>
/// <returns></returns>
[HttpPatch("{entryId}")]
public async Task<ActionResult> Patch(int entryId, [FromBody] JsonPatchDocument<EntryModel> patchDocument)
{
if (patchDocument == null)
{
return BadRequest();
}
var existingEntry = _mapper.Map<EntryModel>(await _entryService.Get(entryId));
// Apply changes
patchDocument.ApplyTo(existingEntry);
var entry = _mapper.Map<Entry>(existingEntry);
var updatedEntry = _mapper.Map<Entry>(await _entryService.Update(entryId, entry));
return Ok();
}
Take a look at this page: https://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-3.1看看这个页面: https://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-3.1
But the content is something like:但内容是这样的:
[ {
"op": "add",
"path": "/customerName",
"value": "Barry" }, {
"op": "add",
"path": "/orders/-",
"value": {
"orderName": "Order2",
"orderType": null
} } ]
The JsonPatchDocument will not work. JsonPatchDocument 将不起作用。 To make it work you have to add a media type formater.要使其工作,您必须添加一个媒体类型格式化程序。
Install Microsoft.AspNetCore.Mvc.NewtonsoftJson安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson
In startup.cs, after AddControllers() add ->在 startup.cs 中,在 AddControllers() 之后添加 ->
.AddNewtonsoftJson(x => x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }) .AddNewtonsoftJson(x => x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); })
If you need to have JSON as the default media type formatter.如果您需要将 JSON 作为默认媒体类型格式化程序。 Keep it before any other media type of formatter.将其放在任何其他媒体类型的格式化程序之前。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.