调用API时出现接口类型不支持反序列化错误,求更优解决方案
报错根因
.NET 内置的 System.Text.Json 序列化器默认没有提供接口类型的反序列化实现,它无法自动识别接口对应的具体实现类,所以会抛出该错误。
比直接替换为实现类更优的解决方案
方案1:自定义JsonConverter(最推荐,无安全风险,符合面向接口设计)
你不需要修改接口的属性定义,只需要实现对应接口的自定义转换器,指定反序列化时使用的实现类即可。
- 实现转换器代码:
public class MyInterfaceConverter : JsonConverter<MyInterface> { public override MyInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 反序列化时指定用MyClass作为实现类 return JsonSerializer.Deserialize<MyClass>(ref reader, options); } public override void Write(Utf8JsonWriter writer, MyInterface value, JsonSerializerOptions options) { // 序列化时按实际类型输出 JsonSerializer.Serialize(writer, value, value.GetType(), options); } }
- 在Program.cs中注册转换器:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new MyInterfaceConverter()); });
如果后续有多个MyInterface的实现类,只需要在转换器的Read方法中,根据Json的字段特征判断要反序列化的目标实现类即可,不需要修改业务代码里的接口定义。
方案2:使用Newtonsoft.Json的TypeNameHandling配置(适合内部服务场景)
如果你项目用的是Newtonsoft.Json,可以开启自动类型名称注入,序列化时会自动在Json中添加$type字段标识具体实现类,反序列化时自动识别:
- 先安装
Microsoft.AspNetCore.Mvc.NewtonsoftJsonNuget包 - 在Program.cs中配置:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { // Auto表示只有当声明类型和实际类型不一致时才添加$type字段 options.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; });
注意:该方案存在反序列化注入风险,禁止在对外暴露的公网接口中使用,仅推荐内部可信服务之间调用时使用。
方案对比
你目前直接把属性类型改为MyClass的方式虽然简单,但破坏了面向接口的设计原则,后续如果要替换实现类需要修改所有用到该属性的业务代码,扩展性很差。上面两个方案都不需要修改接口定义,保留了面向接口的灵活性。
内容的提问来源于stack exchange,提问作者Devansh Verma
相关产品推荐
相关产品推荐

