向接收泛型抽象类参数的C# WebAPI POST接口传JSON出现输入无效问题
问题根源
- 字段名不匹配:你定义的
Animal<T>基类公开属性是Name和Properties,但POST的JSON用了key和value作为字段名,序列化器无法匹配属性,直接触发校验错误。 - 抽象类无法直接反序列化:默认的JSON序列化器(不管是System.Text.Json还是Newtonsoft.Json)都不能直接实例化抽象类,你接口入参定义为
Animal<JObject>类型,序列化器没有明确的类型实例化规则,自然反序列化失败。 - 泛型参数不匹配:你的派生类
Pig的泛型参数是List<int>,但接口入参用的是Animal<JObject>,就算绕过抽象类实例化问题,泛型参数类型不一致也会导致数据绑定失败。
正确的JSON请求体示例(仅修正字段名,需搭配后续序列化配置才能正常使用)
{ "Name":"pigEntity", "Properties":[ 1, 2, 3, 4, 5, 6 ] }
可选实现方案
方案1:替换入参为非抽象类
最简单的适配方案,直接把Animal<T>的abstract修饰符去掉,或者单独定义一个非抽象的请求模型类作为入参,不需要额外配置序列化规则就能直接绑定上述JSON。
方案2:配置多态序列化支持
如果必须保留抽象基类+多派生类的设计,可通过内置特性或者自定义转换器实现多态反序列化:
- 如果你用System.Text.Json,可直接给基类加
JsonDerivedType特性配置类型鉴别器:
[JsonDerivedType(typeof(Pig), typeDiscriminator: "pigEntity")] public abstract class Animal<T> { public string Name { get; set; } public virtual T Properties{ get; set; } }
配置完成后序列化器会根据typeDiscriminator的值自动实例化对应的派生类,你也可以配置用现有的Name字段作为类型鉴别器。
- 如果你用Newtonsoft.Json,可自定义
JsonConverter,在反序列化时读取Name字段的值,手动返回对应的派生类实例。
方案3:直接用JObject/dynamic接收参数
如果不想调整实体类结构,可把接口入参改为[FromBody] JObject request,然后自己手动读取字段值映射到对应的实体类,灵活度最高,适合派生类类型多、结构差异大的场景。
内容的提问来源于stack exchange,提问作者mievvin
相关产品推荐
相关产品推荐

