反序列化泛型 Dto 的包装器

Deserialize wrapper of generic Dto's

提问人:Zenith 提问时间:11/17/2023 最后编辑:dbcZenith 更新时间:11/21/2023 访问量:37

问:

我通过以下方式实现了 dto 的包装器。我正在尝试反序列化此包装器以获得正确的 Dto。我尝试应用我所知道的有关反序列化的所有知识,但我无法让它工作。序列化包装器也可能很困难。 是一个通用接口,所以我使用 JsonDerivedTypeAttribute 和 FallBackToNearestAncestor 来序列化 Dto。值得庆幸的是,这在包装器中序列化 Dto 时也有效:Dto

using System.Text.Json.Serialization;
using System;


public interface Dto<T> : Dto where T : Entity;

[JsonDerivedType(derivedType: typeof(CourseDto))]
[JsonDerivedType(derivedType: typeof(DeletedDto))]
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
public interface Dto
{
    string Id { get; init; }
};

public interface Entity
{
}

public sealed record CourseEntity(Guid id, string Name) : Entity;

public sealed record DeletedDto(string Id) : Dto;

public sealed record CourseDto(
    string Id,
    string Name
) : Dto<CourseEntity>;

允许

public sealed record SynchronizableWrapper<T>(T[]? Added, T[]? Updated, DeletedDto[]? Deleted)
    : SynchronizableWrapper(Added, Updated, Deleted) where T : class, Dto
{
    public new T[]? Added => (T[]?) base.Added;
    public new T[]? Updated => (T[]?) base.Updated;
    public new DeletedDto[]? Deleted => base.Deleted;
}

public record SynchronizableWrapper(Dto[]? Added, Dto[]? Updated, DeletedDto[]? Deleted)
{
    public Dto[]? Added { get; set; } = Added;
    public Dto[]? Updated { get; set; } = Updated;
    public DeletedDto[]? Deleted { get; set; } = Deleted;
}

要序列化:

{
  "added": [
    {
      "id": "6a38a67c-46e3-497e-ab5f-3fa6b8d15cc4",
      "name": "SomeCourse's name",
    }
  ],
  "updated": [],
  "deleted": [
    {
      "id": "6a38a67c-46e3-497e-ab5f-3fa6b8d15cc4"
    }
  ]
}

现在,我希望反序列化为一个 SynchronizableWrapper,其中 T : Dto,或者反序列化为 SynchronizableWrapper<Dto>其中 T : Entity:

public async Task<SynchronizableWrapper?> AsyncGetChangedEntities<T, T2>() where T : class, Dto<T2> where T2 : class, Entity
{
    var query = "someURI";
    var response = await httpClient.GetAsync(query);

    //validate response

    if (response.StatusCode is HttpStatusCode.NoContent) return null;

    return await response.Content
        .ReadFromJsonAsync<SynchronizableWrapper<T>>(_serializerOptions);
// returns an empty SynchronizableWrapper :((
}

我尝试使用JsonDerivedTypeAttributes,但这不起作用。尝试反序列化为 SynchronizableWrapper、SynchronizableWrapper<Dto>、SynchronizableWrapper,甚至只是硬编码的 SynchronizableWrapper 或 SynchronizableWrapper<Dto>也无济于事。

C# JSON net-core system.text.json 多态反序列化

评论

2赞 dbc 11/18/2023
请您编辑您的问题以分享一个最小的可重复示例吗?就目前而言,您的代码无法编译,请参阅 dotnetfiddle.net/4stmpA。我收到两个错误:类型“Entity”中不存在类型名称“Entity”,并且找不到类型或命名空间名称“CourseEntity”。
0赞 dbc 11/21/2023
假设您正在调用 ,然后只需设置或似乎可以解决问题,请参阅 dotnetfiddle.net/8Wb9P4dotnetfiddle.net/Xzljkd。这能解决您的问题吗?如果是这样,这看起来是 JsonSerializer.Deserialize 失败的副本。如果没有,请编辑您的问题以分享一个完整的最小可重现示例,包括 your 和 types 和 .AsyncGetChangedEntities<CourseDto, CourseEntity>();PropertyNameCaseInsensitive = truePropertyNameCaseInsensitive.PropertyNamingPolicy = JsonNamingPolicy.CamelCase_serializerOptionsTT2

答: 暂无答案