JSON Patch报错路径段目标位置未找到,实体属性与请求路径不匹配如何处理
错误根因
[Column("fax")]是EF Core用于映射数据库字段的特性,仅作用于EF和数据库的交互逻辑,和JSON Patch的属性路径匹配完全无关。JSON Patch的路径匹配默认依赖JSON序列化配置的属性命名规则,你请求路径用的是蛇形命名的fax_number,但C#实体属性是帕斯卡命名的FaxNumber,默认匹配规则下找不到对应属性,因此抛出异常。
解决方案
根据你的项目场景可以选择以下任意一种方案:
方案1:单个属性加JSON序列化特性(改动最小,适合仅少数属性需要映射的场景)
直接在Address实体的FaxNumber属性上加对应的JsonProperty特性即可,不需要修改其他业务代码:
- 如果你用的是ASP.NET Core默认的System.Text.Json序列化器:
[Column("fax")] [JsonPropertyName("fax_number")] public string FaxNumber { get; set; }
- 如果你用的是Newtonsoft.Json序列化器:
[Column("fax")] [JsonProperty("fax_number")] public string FaxNumber { get; set; }
方案2:全局配置JSON命名策略(适合整个项目API统一用蛇形命名的场景)
在Program.cs中配置全局JSON命名规则,所有帕斯卡命名的C#属性都会自动映射为蛇形的JSON字段,不需要每个属性单独加特性:
- System.Text.Json配置:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower; });
- Newtonsoft.Json配置:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() }; });
方案3:新增DTO中间层适配(生产环境推荐方案)
不直接把JsonPatchDocument作用在EF实体上,先定义和API请求字段匹配的DTO,Patch完成后再映射回实体,既可以解决命名匹配问题,还能避免API直接暴露数据库实体结构,安全性更高:
- 定义Patch专用DTO:
public class AddressPatchDto { public string FaxNumber { get; set; } // 其他需要支持Patch的字段 }
- 调整业务代码:
public async Task<int> PatchAddressAsync(int id, JsonPatchDocument<AddressPatchDto> request) { var cust = await _dbContext.Address.FirstOrDefaultAsync(x => x.ID == id); if (cust == null) throw new NotFoundException($"The supplied id is not valid."); // 实体映射到DTO var addressDto = _mapper.Map<AddressPatchDto>(cust); // 应用Patch操作到DTO request.ApplyTo(addressDto); // 修改后的DTO映射回实体 _mapper.Map(addressDto, cust); await _dbContext.SaveChangesAsync(default(CancellationToken)); return cust.ID; }
内容的提问来源于stack exchange,提问作者Rasik
相关产品推荐
相关产品推荐

