使用HTTPClient的C#HTTP修补程序

使用HTTPClient的C#HTTP修补程序,c#,.net-core,patch,http-patch,C#,.net Core,Patch,Http Patch,我已经在dot net core 3.1中使用测试服务器编写了一个测试,我正在尝试对端点执行补丁请求。然而,由于我对使用补丁还不熟悉,我对如何发送端点所期望的正确对象有点困惑 [Fact] public async Task Patch() { var operations = new List<Operation> { new Operation("replace", "entryId", "'att

我已经在dot net core 3.1中使用测试服务器编写了一个测试,我正在尝试对端点执行补丁请求。然而,由于我对使用补丁还不熟悉,我对如何发送端点所期望的正确对象有点困惑

[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());
}
[事实]
公共异步任务修补程序()
{
var操作=新列表
{
新操作(“替换”、“entryId”、“考勤界面”,5)
};
var jsonPatchDocument=new jsonPatchDocument(operations,new DefaultContractResolver());
//表演
var content=newstringcontent(JsonConvert.SerializeObject(jsonPatchDocument),Encoding.UTF8,“application/json”);
var httpResponse=await HttpClient.PatchAsync($“v1/Entry/1”,content);
var actual=await-httpResponse.Content.ReadAsStringAsync();
}
[HttpPatch(“{entryId}”)]
公共异步任务

谢谢,
尼克

看看这一页:

但内容是这样的:

[   {
    "op": "add",
    "path": "/customerName",
    "value": "Barry"   },   {
    "op": "add",
    "path": "/orders/-",
    "value": {
      "orderName": "Order2",
      "orderType": null
    }   } ]

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

  • 没有依赖项,JsonPatchDocument似乎无法工作
    services.AddControllers().AddNewtonsoftJson()在Startup.cs中。这来自Nuget软件包“Microsoft.AspNetCore.Mvc.Newtonsoft.json”
  • 有一种比@Neil的答案更容易创建数组的方法。这是:
    var patchDoc=new JsonPatchDocument().Replace(o=>o.EntryTypeId,5)
  • 您需要此特定的媒体类型:
    var content=newstringcontent(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();
}
//
///验证PUT/Entrys是否正常工作并返回更新的记录
/// 
[事实]
公共异步任务修补程序()
{
var patchDoc=new JsonPatchDocument()
.Replace(o=>o.EntryTypeId,5);
var content=newstringcontent(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.Equal(HttpStatusCode.OK,httpResponse.StatusCode);
True(httpResponse.IsSuccessStatusCode);
}
/// 
///要执行部分更新的端点
/// 
/// 
[HttpPatch(“{entryId}”)]
公共异步任务修补程序(int entryId,[FromBody]JsonPatchDocument patchDocument)
{
if(patchDocument==null)
{
返回请求();
}
var existingEntry=\u mapper.Map(wait\u entryService.Get(entryId));
//应用更改
patchDocument.ApplyTo(现有条目);
var条目=_mapper.Map(existingEntry);
var updatedEntry=\u mapper.Map(wait\u entryService.Update(entryId,entry));
返回Ok();
}

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

  • 安装Microsoft.AspNetCore.Mvc.NewtonsoftJson

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

    .AddNewtonsoftJson(x=> x、 SerializerSettings.ContractResolver= 新的CamelCasePropertyNamesContractResolver();})

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


  • 在做了大量的挖掘之后,我最终自己解决了这个问题。请参阅答案,了解如何使用TestServer实现它。