.NET Core中JSON Patch处理抽象类(继承)失败问题求助
问题分析与解决方案
错误原因
你的HrFormSectionV1.BuildingComponents是ICollection<HrBuildingComponentsV1>类型,而HrBuildingComponentsV1是抽象类。JSON Patch的默认序列化器无法直接实例化抽象类,也不知道要将传入的JSON映射到哪个具体子类(比如HrTextBuildingComponentV1),因此抛出"值对目标位置无效"的错误。
解决方案
需要自定义JSON Patch的对象转换器,根据请求中的type枚举值创建对应的具体组件实例,再完成反序列化。
步骤1:实现自定义ObjectConverter
创建一个处理抽象组件类型的转换器,根据type字段选择具体子类:
using Microsoft.AspNetCore.JsonPatch.Adapters; using System.Text.Json; public class AbstractBuildingComponentConverter : IObjectConverter { public bool TryCreateObject(Type type, JsonElement element, out object? value) { // 只处理HrBuildingComponentsV1抽象类型 if (type != typeof(HrBuildingComponentsV1)) { value = null; return false; } // 读取请求中的type字段 if (!element.TryGetProperty("type", out var typeElement)) { value = null; return false; } // 根据枚举值创建对应具体组件实例 var componentType = (BuildingComponentType)typeElement.GetInt32(); HrBuildingComponentsV1 component = componentType switch { BuildingComponentType.Text => new HrTextBuildingComponentV1(), // 在这里添加其他组件类型的映射,比如文本域、下拉框等 _ => throw new NotSupportedException($"不支持的组件类型:{componentType}") }; // 将JSON反序列化到具体实例 using var jsonDoc = JsonDocument.Parse(element.GetRawText()); JsonSerializer.Deserialize(jsonDoc.RootElement, component.GetType()); value = component; return true; } }
步骤2:注册自定义转换器
在Program.cs(或Startup.cs)中,将自定义转换器添加到JSON Patch的配置里:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddJsonPatchOptions(options => { // 注册自定义转换器 options.ObjectConverters.Add(new AbstractBuildingComponentConverter()); }); var app = builder.Build(); // 其他中间件配置... app.Run();
步骤3:补充注意事项
- 确保
HrFormSectionV1的BuildingComponents集合已初始化:在构造函数中添加BuildingComponents = new List<HrBuildingComponentsV1>();,避免空引用异常。 - 保持请求字段与模型属性的命名一致性:如果你的JSON序列化采用驼峰命名,建议请求中使用
sectionId而非sectionid,或者在JSON配置中开启大小写不敏感匹配。 - 验证
type枚举值:确保请求中的type值(比如0)与BuildingComponentType.Text的枚举值完全对应。
内容的提问来源于stack exchange,提问作者mohsinali1317
相关产品推荐
相关产品推荐

