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

C#如何阻止JSON请求体重复键自动移除或让请求失败

刚好遇到过类似的场景,给你两个针对性的解决方案,看你更倾向哪种需求:

方案一:让含重复键的请求直接失败

默认的JSON序列化器(不管是Newtonsoft.Json还是System.Text.Json)处理重复键时,要么自动保留最后一个,要么可以配置成遇到重复键就抛出异常。我们只需要调整序列化配置,就能让这类请求直接返回400错误。

如果你用的是Newtonsoft.Json(ASP.NET Core常用)

在Startup.cs或者Program.cs里配置Json选项,开启重复键报错:

services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        // 遇到重复属性名时直接抛出异常
        options.SerializerSettings.DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error;
    })
    .AddOData(/* 你的OData配置 */);

如果你用的是System.Text.Json(.NET Core 3.0+ 默认)

同样在配置里关闭允许重复键:

services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 不允许JSON里出现重复的属性名,否则抛出异常
        options.JsonSerializerOptions.AllowDuplicateNames = false;
    })
    .AddOData(/* 你的OData配置 */);

配置完成后,当客户端传入含重复键的JSON时,序列化器会直接抛出异常,框架自动返回400 Bad Request,请求不会进入你的Func_Name方法。

方案二:保留所有重复键(不自动去重)

因为IDictionary<string, string>本身不允许重复键,所以默认绑定会自动去重。要保留重复键,得换一种接收方式:

方式1:改用List<KeyValuePair<string, string>>接收

直接修改请求参数的类型,让序列化器把所有键值对(包括重复的)转换成列表:

[HttpPost]
[ODataRoute("some/odata/route")]
public async Task<HttpResponseMessage> Func_Name(List<KeyValuePair<string, string>> request)
{
    // 这里request会包含所有键值对,比如两个"Bob"的条目:
    // [("Bob", "Doctor"), ("Tim", "Engineer"), ("Bob", "Sailor")]
    // 后续业务逻辑可以自行处理重复键
    ...
}

注意:如果客户端传的是标准的对象格式JSON,Newtonsoft.Json和System.Text.Json都能自动把它解析成List<KeyValuePair>,不需要额外配置。

方式2:手动读取原始请求内容解析

如果需要更灵活的控制,可以直接读取原始请求体,用JsonTextReader遍历所有属性(包括重复的):

[HttpPost]
[ODataRoute("some/odata/route")]
public async Task<HttpResponseMessage> Func_Name()
{
    // 读取原始请求内容
    var rawJson = await Request.Content.ReadAsStringAsync();
    var allKeyValuePairs = new List<KeyValuePair<string, string>>();

    using (var reader = new JsonTextReader(new StringReader(rawJson)))
    {
        reader.DateParseHandling = DateParseHandling.None;
        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.PropertyName)
            {
                string key = reader.Value.ToString();
                // 移动到属性值的位置
                reader.Read();
                string value = reader.Value?.ToString() ?? string.Empty;
                allKeyValuePairs.Add(new KeyValuePair<string, string>(key, value));
            }
        }
    }

    // allKeyValuePairs现在包含所有重复的键值对
    ...
}

这种方式完全绕开了默认的模型绑定,能100%保留JSON里的所有键值对,适合需要精细处理的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:08:22