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

C# API反序列化Dictionary<string,dynamic>遇JsonElement转换问题求方案

C# API Dictionary<string,dynamic>反序列化为原生类型解决方案

方案1:替换默认序列化器为Newtonsoft.Json

System.Text.Json作为ASP.NET Core默认序列化器,对dynamic类型的反序列化默认返回JsonElement对象,而Newtonsoft.Json会自动将JSON值映射为.NET原生类型,是最便捷的解决方案:

  • 第一步:安装NuGet包 Microsoft.AspNetCore.Mvc.NewtonsoftJson
  • 第二步:修改服务注册配置(Program.cs示例):
var builder = WebApplication.CreateBuilder(args);
// 注册控制器时添加Newtonsoft.Json支持
builder.Services.AddControllers()
    .AddNewtonsoftJson();

配置完成后,原有代码无需修改,incomingData中的值会直接反序列化为string、int等原生类型,不会再触发类型转换异常。

方案2:自定义System.Text.Json转换器(不更换序列化器)

如果需要保留System.Text.Json作为默认序列化器,可以自定义JsonConverter实现动态类型的自动转换:

  1. 实现自定义转换器:
using System.Text.Json;
using System.Text.Json.Serialization;

public class DynamicDictionaryConverter : JsonConverter<Dictionary<string, dynamic>>
{
    public override Dictionary<string, dynamic>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        return ParseJsonElement(doc.RootElement);
    }

    private Dictionary<string, dynamic> ParseJsonElement(JsonElement element)
    {
        var result = new Dictionary<string, dynamic>();
        foreach (var property in element.EnumerateObject())
        {
            result[property.Name] = ParseValue(property.Value);
        }
        return result;
    }

    private dynamic ParseValue(JsonElement value)
    {
        return value.ValueKind switch
        {
            JsonValueKind.String => value.GetString()!,
            JsonValueKind.Number => value.TryGetInt32(out var intVal) ? intVal : value.GetDecimal(),
            JsonValueKind.True => true,
            JsonValueKind.False => false,
            JsonValueKind.Null => null!,
            JsonValueKind.Object => ParseJsonElement(value),
            JsonValueKind.Array => value.EnumerateArray().Select(ParseValue).ToList(),
            _ => value.ToString()!
        };
    }

    public override void Write(Utf8JsonWriter writer, Dictionary<string, dynamic> value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, options);
    }
}
  1. 注册转换器到System.Text.Json配置:
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new DynamicDictionaryConverter());
    });

方案3:轻量取值方案(无需修改序列化配置)

如果不想改动全局序列化规则,直接通过JsonElement自带的取值方法获取对应类型值即可,代码修改量最小:

string item01Id = incomingData["item01Id"].GetString();
int item01Value = incomingData["item01Value"].GetInt32();
string item02Id = incomingData["item02Id"].GetString();
string item02Value = incomingData["item02Value"].GetString();

注意:使用dynamic作为参数类型会丢失编译时类型检查,存在运行时类型错误风险,若接口参数结构可预期,优先定义强类型DTO作为入参。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 00:36:01