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

WebApi传递动态参数的最佳实践 如何解决Dictionary反序列化类型问题

方案1:使用JsonNode/JToken作为Dictionary的值类型(最推荐)

这是修改成本最低的方案,完全适配现有代码结构,同时解决object类型丢失类型信息的问题:

  • .NET 6及以上版本可以直接用自带的System.Text.Json.Nodes.JsonNode
  • 用Newtonsoft.Json的场景可以替换为JToken

修改后的代码示例:

[HttpPost]
void Foo(Dictionary<string, JsonNode> prm)
{
    var sql = "whatever";
    var sqlPrms = new List<SqlParameter>();

    if (prm.TryGetValue("Condition1",out var c1))
    {
        sql += " and Condition1=@c1";
        // 可显式转换为目标类型,也可以直接调用GetValue<object>()获取保留原始类型的装箱值
        sqlPrms.Add(new SqlParameter("c1", c1.GetValue<object>()));
    }

    if (prm.TryGetValue("Condition2", out var c2))
    {
        sql += " and Condition2=@c2";
        sqlPrms.Add(new SqlParameter("c2", c2.GetValue<object>()));
    }

    ExecuteSql(sql, sqlPrms);
}

JsonNode在反序列化阶段会完整保留JSON原始值的类型信息,不会出现普通Dictionary<string, object>反序列化时数字默认转成long、类型不匹配的问题。

方案2:自定义动态参数结构(适合需要强类型约束的场景)

如果需要前端明确指定参数类型避免歧义,可以自定义轻量级参数包装类:

public class DynamicQueryParam
{
    public object Value { get; set; }
    // 存储参数的实际类型,比如TypeCode.Int32、TypeCode.String等
    public TypeCode ValueType { get; set; }
}

// Action签名修改为
[HttpPost]
void Foo(Dictionary<string, DynamicQueryParam> prm)

取值时可以根据ValueType做显式类型转换,完全避免类型匹配错误,适合对数据精度要求高的场景。

方案3:直接读取请求JSON体

如果查询条件的灵活性要求极高,也可以直接把请求体读取为JsonDocument自行解析,不需要依赖模型绑定:

[HttpPost]
void Foo([FromBody] JsonDocument doc)
{
    var root = doc.RootElement;
    // 自行遍历属性、提取值和类型
}

所有方案都保留了参数化查询的逻辑,不会引入SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:36:02