【问题标题】:ASP.net Core MVC not calling System.Text.Json's custom polymorphic JsonConverter on abstract resultASP.net Core MVC 没有在抽象结果上调用 System.Text.Json 的自定义多态 JsonConverter
【发布时间】:2021-05-14 13:27:25
【问题描述】:

我有一个从 Microsoft.AspNetCore.Mvc.ControllerBase 派生的 .NET Core 3.1 控制器,结果输出时不会调用自定义 json 转换器。

产品

public interface IProduct { ... }

控制器:

[HttpGet("{id}")]
public IProduct Get(string id)
{
   IProduct product = _data.GetProduct(id);
   return product;
}

[HttpPut]
public Task Save(IProduct product)
{
    return _data.Save(product);
}

JsonConverter

public class ProductConverter : System.Text.Json.Serialization.JsonConverter<IProduct> 
{
    public override IProduct Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
         // this code works from unit tests, trust me :)
    }

    public override void Write(Utf8JsonWriter writer, IProduct value, JsonSerializerOptions options) 
    {
        // this code works from unit tests, trust me :)
    }
}

启动

services
  .AddControllers()
  .AddJsonOptions(options => {
      options.JsonSerializerOptions.Converters.Add(new ProductConverter());
  });

症状

  • 当控制器的动作方法Save被调用时,ProductConverter.Read被调用
  • 当控制器的动作方法Get被调用时,ProductConverter.Write方法被调用
  • 我得到了IProduct实际执行的json结果

我是否遗漏了什么或做错了什么?

【问题讨论】:

标签: c# asp.net-core system.text.json


【解决方案1】:

Damien_The_UnbelieverWhy when return interface in a web api method, I get the values of inherited class with interface values?answer 已经过时,但显然仍适用于 ASP.NET Core 3.1:

当它到达 Json 序列化器时,它并不关心方法的返回类型是什么。它只知道“我有这个对象,让我们看看我能用它做什么”。

因此不会调用您的转换器,因为返回的实际具体类型不是IProduct,因此基类实现JsonConverter&lt;IProduct&gt;.CanConvert(objectType) 返回false

public override bool CanConvert(Type typeToConvert)
{
    return typeToConvert == typeof(T);
}

要使您的ProductConverter 也适用于IProduct 的具体实现,请按如下方式覆盖CanConvert

public override bool CanConvert(Type typeToConvert) => 
    typeof(IProduct).IsAssignableFrom(typeToConvert);

请注意,如果Read()Write() 的实现尝试通过使用具体类型递归调用序列化程序来生成传入具体产品的“默认”序列化,则可能会出现堆栈溢出。要解决这个问题,您可以:

【讨论】:

  • 谢谢解答
猜你喜欢
  • 2020-10-05
  • 2022-12-14
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 2020-05-01
相关资源
最近更新 更多