当前位置: 首页 > 知识库问答 >
问题:

如何反序列化不同类型的派生类?

酆翔宇
2023-03-14

我试图反序列化2种不同类型的列表,包括它们的派生类

为了更好地解释它,我做了下面的例子

我有2个系统:
API系统

  public class ItemController : ControllerBase
    {
        private readonly ILogger<ItemController> _logger;

        public ItemController(ILogger<ItemController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public async Task<ActionResult<BaseItem>> Get()
        {
            var items = new List<BaseItem>();
            items.Add(new BaseItem { Id = 1 });
            items.Add(new Item { Id = 2, ItemName = "some name", ItemType = "some type" });

            return Ok(items);
        }
    }

与下列实体合作:

namespace SomeService.API.Entities
{
    public class BaseItem
    {
        public int Id { get; set; }
    }
    public class Item: BaseItem
    {
        public string ItemType { get; set; }
        public string ItemName { get; set; }
    }
}

应用系统

static async Task Main(string[] args)
        {
            var client = new HttpClient();
            var response = await client.GetAsync($"http://localhost:5000/Item");
            Thread.Sleep(3000);
            var dataAsString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            JsonSerializerSettings settings = new JsonSerializerSettings();
            var obj = JsonConvert.DeserializeObject<List<BaseItem>>(dataAsString);

        }  

使用以下DTO

namespace SomeSystem.APP.DTOs
{
    public class BaseItem
    {
        public int Id { get; set; }
    }
    public class Item : BaseItem
    {
        public string ItemType { get; set; }
        public string ItemName { get; set; }
    }
}

使用此示例,API系统返回一个列表

将应用程序DTO反序列化到列表后,反序列化时出现问题

1我想的解决方法是创建一个类库并将所有实体移动到那里,然后将两个系统引用到这个类库,因此我将在两个系统中拥有相同类型的实体,但是,我不想使用这个工作,因为我不希望这两个系统之间的第三方依赖关系,我希望它们完全独立。所以我的问题是,
有没有其他工作可以让我在应用环境中以我能够使用的方式反序列化json派生类属性?


共有1个答案

郑景胜
2023-03-14

你应该处理这个项目。我认为您的混淆使用的是var,因为您假设的是匿名或变体类型,但不是。根据具体情况,您不会返回一个或另一个。

你写道:

 var items = new List<BaseItem>();
            items.Add(new BaseItem { Id = 1 });
            items.Add(new Item { Id = 2, ItemName = "some name", ItemType = "some type" });

但在编译中,这段代码实际上意味着:

 List<Item>  items = new List<Item>();
            items.Add(new Item { Id = 1, ItemName = null, ItemType = null});
            items.Add(new Item { Id = 2, ItemName = "some name", ItemType = "some type" });

作为架构建议,您不应该混合类来响应相同的服务,或者您应该使用您将返回的真实。

如果您想要的是变体类型(我不建议),您应该阅读@Eric comment的问题。但是动态对象不是var

 类似资料:
  • 我有一个带有Object类型属性的基类型(一段遗留代码,许多项目都使用这个基类型)。后来添加了基类型的泛型版本,将属性公开为泛型类型。 使用ServiceStack.Text序列化和反序列化泛型类型将设置基类(type object)上的属性,而不是派生类上更特定的类型。 重现错误的简单控制台应用程序如下所示: 感谢任何帮助。 基于这个答案,我通过使和从一个新的抽象基类继承来解决这个问题,如下所示

  • 序列化和反序列化的方式不同于 我已经创建了两个序列化程序 和 我用Jackson查看了序列化/反序列化映射 ,但找不到解决方案。

  • 这是保存过程开始的地方。我定义了一个抽象方法,以后在运行时已知的类中实现。 这里我知道的类型,我想调用一个方法。 所以问题是ConfigurationPersistenceHelper中的方法。运行此方法时,配置中得到的不是而是。 我知道我可以在每个具体应用程序类的方法中实现反序列化器逻辑。但这会导致大量重复代码。这是我目前的解决方案。 此外,我知道我可以将类型从(其中类型在运行时仍然可用)传递给

  • 假设我有一个从Point2D继承的类Point3D和一个从Drawing2D继承的类Drawing3D。 我希望两个类Drawing2D和Drawing3D具有相同的属性名Points,这将是Drawing2D的Point2D列表,以及Drawing3D的Point3D列表。 由于具有相同的属性名,我希望Drawing3D能够在属性点上受益于Drawing2D方法。问题是我不能使用覆盖,因为类型不

  • 问题内容: 我正在尝试使用Gson 反序列化a ,值的类型可以变化,值“ in_wanted”可以是a 或a 。 in_wanted为: in_wanted为: 每当“ in_wanted”的值为布尔值时,我都需要该对象,并且需要一个反序列化器以返回null。用Gson做到这一点的最佳方法是什么? 问题答案: 您可以使用自定义解串器来完成此操作。首先,我们应该创建可以表示您的JSON的数据模型。

  • 本文向大家介绍PHP 不同类型的序列化,包括了PHP 不同类型的序列化的使用技巧和注意事项,需要的朋友参考一下 示例 生成值的可存储表示形式。 这对于存储或传递PHP值而不丢失其类型和结构很有用。 要再次将序列化的字符串转换为PHP值,请使用unserialize()。 序列化字符串 序列化双精度 序列化浮点数 浮点数被序列化为双打。 序列化整数 序列化布尔值 序列化null 序列化数组 序列化对