You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Web API中泛型DTO的JSON反序列化及列表使用方案咨询

C# Web API中泛型EntryDto的JSON序列化/反序列化方案

一、开箱即用的反序列化方案

C#主流的JSON序列化库都支持直接泛型反序列化,完全满足你的需求:

1. System.Text.Json(.NET Core 3.0+内置)

Web API默认使用的官方库,直接指定泛型类型即可完成反序列化:

// 示例:反序列化为string类型的EntryDto
var json = "{\"Value\": \"hello world\"}";
var stringEntry = JsonSerializer.Deserialize<EntryDto<string>>(json);

// 示例:反序列化为int类型的EntryDto
var intJson = "{\"Value\": 123}";
var intEntry = JsonSerializer.Deserialize<EntryDto<int>>(intJson);

2. Newtonsoft.Json(Json.NET)

如果项目依赖老牌的Json.NET,写法类似:

var boolJson = "{\"Value\": true}";
var boolEntry = JsonConvert.DeserializeObject<EntryDto<bool>>(boolJson);

二、包含EntryDto列表的请求/响应类

完全可以创建这类泛型请求/响应类,分两种场景处理:

1. 单一类型的列表

如果列表中所有EntryDto的泛型类型T一致,直接定义泛型容器类即可:

// 泛型请求类
public class EntryListRequest<T>
{
    public List<EntryDto<T>> Entries { get; set; } = new List<EntryDto<T>>();
}

// 泛型响应类
public class EntryListResponse<T>
{
    public List<EntryDto<T>> Entries { get; set; } = new List<EntryDto<T>>();
    public bool IsSuccess { get; set; }
    public string? Message { get; set; }
}

使用时明确指定T的类型:

// 反序列化int类型的请求
var requestJson = "{\"Entries\": [{\"Value\": 1}, {\"Value\": 2}, {\"Value\": 3}]}";
var intRequest = JsonSerializer.Deserialize<EntryListRequest<int>>(requestJson);

// 序列化string类型的响应
var stringResponse = new EntryListResponse<string>
{
    Entries = new List<EntryDto<string>>
    {
        new() { Value = "first" },
        new() { Value = "second" }
    },
    IsSuccess = true
};
var responseJson = JsonSerializer.Serialize(stringResponse);

2. 混合类型的列表(T为不同类型)

如果需要在同一个列表中存放不同T类型的EntryDto(同时包含string、int、bool等),静态泛型无法直接支持,可通过两种方案解决:

方案一:使用EntryDto兼容多类型

反序列化后通过类型判断处理不同值:

var mixedJson = "{\"Entries\": [{\"Value\": \"test\"}, {\"Value\": 456}, {\"Value\": false}]}";
var mixedEntries = JsonSerializer.Deserialize<List<EntryDto<object>>>(mixedJson);

foreach (var entry in mixedEntries)
{
    switch (entry.Value)
    {
        case string s:
            Console.WriteLine($"字符串值:{s}");
            break;
        case int i:
            Console.WriteLine($"整数值:{i}");
            break;
        case bool b:
            Console.WriteLine($"布尔值:{b}");
            break;
    }
}

注意:System.Text.Json默认会将JSON数字反序列化为long,若要精准识别int,需配置序列化选项:

var options = new JsonSerializerOptions
{
    NumberHandling = JsonNumberHandling.AllowReadingFromString
};

方案二:通过多态序列化实现类型识别

创建非泛型基类,让EntryDto继承并配置类型鉴别:

public abstract class EntryDtoBase
{
    public abstract object GetValue();
}

public class EntryDto<T> : EntryDtoBase
{
    public T Value { get; set; } = default!;

    public override object GetValue() => Value;
}

配置System.Text.Json的多态序列化规则:

var options = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { typeInfo =>
            {
                if (typeInfo.Type == typeof(EntryDtoBase))
                {
                    typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                    {
                        DerivedTypes =
                        {
                            new JsonDerivedType(typeof(EntryDto<string>), "string"),
                            new JsonDerivedType(typeof(EntryDto<int>), "int"),
                            new JsonDerivedType(typeof(EntryDto<bool>), "bool"),
                            new JsonDerivedType(typeof(EntryDto<double>), "double")
                        }
                    };
                }
            }
        }
    }
};

// 序列化混合类型列表
var mixedList = new List<EntryDtoBase>
{
    new EntryDto<string> { Value = "demo" },
    new EntryDto<int> { Value = 789 },
    new EntryDto<bool> { Value = true }
};
var serializedJson = JsonSerializer.Serialize(mixedList, options);

// 反序列化
var deserializedList = JsonSerializer.Deserialize<List<EntryDtoBase>>(serializedJson, options);

此方案需要前端在JSON中携带类型标识(如"$type": "string"),确保后端能正确识别类型。

注意事项

  • 前端传递JSON时,需保证Value的类型与后端预期的T类型匹配,否则会抛出反序列化异常。
  • 对于可空类型(如int?),需确保JSON中的值为null或对应类型的有效值。
  • 混合类型场景建议优先使用EntryDto<object>方案,业务逻辑更简洁;多态方案适合强类型要求高的场景。

内容的提问来源于stack exchange,提问作者kristofdc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:47:32