3

我已经使用 dot net core 3.1 中的测试服务器编写了一个测试,并且我正在尝试向端点发出 PATCH 请求。但是,由于我是使用 PATCH 的新手,所以我有点不知道如何发送端点期望的正确对象。

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

在示例中,我创建了一个带有操作列表的 JsonPatchDocument,将其序列化为 JSON,然后使用 HTTP 客户端和端点的 URL 执行 PatchAsync。

所以我的问题是我应该修补的对象的形状是什么,并且我通常正确地执行此操作?

我尝试发送如下图所示的 EntryModel,但是 patchDocument.Operations 有一个空列表。

在此处输入图像描述

谢谢,尼克

4

3 回答 3

2

我最终通过做几件事来解决我的问题:

  • 如果没有 Startup.cs中的依赖项,JsonPatchDocument 似乎无法工作 services.AddControllers().AddNewtonsoftJson();。这是来自 Nuget 包 `Microsoft.AspNetCore.Mvc.Newtonsoft.json。
  • 有一种比@Neil 的答案更简单的方法来创建数组。这是: var patchDoc = new JsonPatchDocument<EntryModel>().Replace(o => o.EntryTypeId, 5);
  • 您需要这种特定的媒体类型: var content = new StringContent(JsonConvert.SerializeObject(patchDoc), Encoding.UTF8, "application/json-patch+json");

这是完整的代码:

/// <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();
}
于 2020-07-23T15:13:17.527 回答
0

看看这个页面:https ://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-3.1

但内容是这样的:

[   {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"   },   {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }   } ]
于 2020-07-23T13:07:54.807 回答
-1

JsonPatchDocument 将不起作用。要使其工作,您必须添加一个媒体类型格式化程序。

  1. 安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson

  2. 在 startup.cs 中,在 AddControllers() 之后添加 ->

    .AddNewtonsoftJson(x => x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); })

  3. 如果您需要将 JSON 作为默认媒体类型格式化程序。将其放在任何其他媒体类型的格式化程序之前。

于 2021-02-20T20:47:48.920 回答