使用Postman向ASP.NET Core WebAPI发送PATCH请求时解析错误排查
问题分析与修复方案
嘿,我来帮你排查下这个PATCH请求失败的问题,主要是两个核心原因:格式不符合规范,加上模型属性类型的限制,具体来说:
1. JSON Patch的格式完全错了
JSON Patch规范明确要求请求体必须是包含操作的数组——哪怕只有一个修改操作,也得用[]把它包起来:
- 你第一种用普通JSON对象
{ "ItemIds": ["xyz","123"] }的方式,根本不是Patch的格式,框架直接就不认; - 第二种虽然写了
replace操作,但没放在数组里,同样不符合规范,所以会报“格式错误无法解析”。
正确的请求体应该是这样的(以替换ItemIds为例):
[{"op":"replace", "path":"/ItemIds", "value": ["xyz","123"]}]
另外别忘了,请求头的Content-Type必须设为application/json-patch+json,不能用普通的application/json,这是框架能识别Patch请求的关键。
2. 模型里的ItemIds类型不支持Patch修改
你的Order类里ItemIds是IEnumerable<string>,这是个只读的枚举接口,当JsonPatchDocument.ApplyTo(target)尝试修改这个属性时,会因为没办法对IEnumerable进行赋值或修改操作而失败——哪怕你后面调用了repo.Update,Patch的应用环节已经先出问题了。
解决办法很简单:把ItemIds改成可修改的集合类型,比如List<string>:
public class Order { public Guid Id { get; set; } public List<string> ItemIds { get; set; } // 把IEnumerable<string>换成List<string> public string Currency { get; set; } }
仓储的Update方法不用大改,因为现在List<string>可以直接赋值,保持原来的逻辑就行:
public void Update(Guid id, Order order) { var target = _orders.FirstOrDefault(o => o.Id == id); if (target != null) { target.ItemIds = order.ItemIds; } }
3. 额外的小检查:NewtonsoftJson配置
你已经加了AddNewtonsoftJson(),这没问题,但如果之后还有Patch相关的序列化问题,可以显式确认下配置(默认是支持的,但显式写出来更稳妥):
services.AddSingleton<IOrderRepository, MemoryOrderRepository>() .AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); });
最后测试步骤
- 把请求头设为
Content-Type: application/json-patch+json; - 发送PATCH请求到
api/order/{你的订单ID},用正确的数组格式请求体; - 调用GET接口验证
ItemIds是不是已经更新成你想要的值了。
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

