首页 > 解决方案 > 使用 JsonPatchDocument 时如何获取属性级序列化错误在 PATCH 调用期间在 .NET Core WebApi 中

问题描述

我正在使用 .NET Core 的 JsonPatch 库实现 HTTP 补丁。(Microsoft.AspNetCore.Mvc.NewtonsoftJson)。微软文档:https ://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-5.0

我能够使用带有以下代码的 JsonPatch 进行部分更新。

DTO:

public class Customer{
   public int Id;
   public string Name;
   public string ZipCode;
}

控制器:

[HttpPatch]
public IActionResult JsonPatchWithModelState([FromBody] JsonPatchDocument<Customer> patchDoc)
{
   var customer = GetExistingCustomerFromDatabase();
   patchDoc.ApplyTo(customer, ModelState);

   if (!ModelState.IsValid)
   {
      return BadRequest(ModelState);
   }

    return new ObjectResult(customer);
}

邮递员示例:(有效数据场景)[名称属性按预期更新]

Request:
{
  "op":"replace",
  "path": "/name",
  "value": "updated-name-XYZ"
}

Response: 200(OK)

当“Name”属性的值为无效数据类型时;返回以下响应。

邮递员示例:(无效数据场景)[例如:试图传递字典对象]

Request:
{
  "op":"replace",
  "path": "/name",
  "value": {"key123": "value123"}
}

Response: 400(Bad Request)
Response Body:
{
    "Customer": [
        "The value '{\r\n  \"key123\": \"value123\"\r\n}' is invalid for target location."
    ]
}

当上述请求发送到 HTTP 操作方法时,断点命中。在那一刻 ModelState.IsValid = true,在应用补丁后:

 patchDoc.ApplyTo(customer, ModelState);

ModelState.IsValid 变为假。并返回 BadRequest(400)。

有没有办法在应用补丁以获得详细的错误消息之前捕获这种无效的数据类型。或者 JsonPatch 是否支持在属性级别(这里:“名称”)而不是实体级别(这里:“客户”)抛出特定的错误消息?

所需的响应正文:

Response: 400(Bad Request)
Response Body:
{
    "Name": [
        "The input was not valid."
    ]
}

这是无效数据情况下 POST 或 PUT 的错误消息。

由于可序列化的错误,Breakpoint 不会在 action 方法处被命中:

"Executing ObjectResult, writing value of type '\"Microsoft.AspNetCore.Mvc.SerializableError\"'.", "Type":"Microsoft.AspNetCore.Mvc.SerializableError"

JsonPatch 也可以实现类似的行为吗?有没有办法在使用 JsonPatchDocument 时用 DTO 类捕获可序列化的错误?

或者任何自定义验证器方法都会有所帮助。

标签: .netasp.net-coreasp.net-core-mvcasp.net-core-webapijson-patch

解决方案


{
  "id" : 1,
  "name":{
           "key123": "value123"
         }
}

尝试将key not name 处的值替换为新值。

{
  "op":"replace",
  "path": "/name/key123",
  "value": "value1234"
}

推荐阅读