C#中处理重复请求参数:保留有值项/多值时报错的实现
重复请求参数处理逻辑修复:重写IsDuplicatedParam方法
需求说明
- 核心目标:识别重复请求参数,保留带值的参数,剔除无值的重复项
- 判定规则:
- 重复参数中仅一个有值:保留该有值项,不触发报错
- 重复参数均有值:返回
Bad request并记录错误日志
场景示例
场景1(合法)
- 原始请求串:
lastname=con&firstname=&firstname=abc&middlename= - 重复参数
firstname一个无值、一个有值,符合规则 - 期望结果:清理后保留
lastname=con、firstname=abc、middlename=
场景2(非法)
- 原始请求串:
lastname=con&firstname=test&firstname=abc&middlename= - 重复参数
firstname两个均有值,违反规则 - 期望结果:返回
Bad request并输出错误日志
现有代码问题
原IsDuplicatedParam方法仅通过字符串替换后的长度差判断重复,逻辑过于简单,无法区分重复参数是否带有有效值,导致无论何种重复情况都返回true,完全不符合需求。
修复后的代码实现
private NameValueCollection parameters; // 处理请求参数的主逻辑方法 public bool ProcessRequestParameters(string decryptedRequest) { // 把请求串拆分成键值对列表,方便后续处理 var paramPairs = decryptedRequest.Split('&') .Select(pair => pair.Split(new[] { '=' }, 2)) .Where(parts => parts.Length == 2) .ToList(); foreach (var paramName in parameters.Cast<string>()) { // 获取当前参数的所有出现实例 var paramEntries = paramPairs.Where(p => p[0] == paramName).ToList(); if (paramEntries.Count > 1) { // 统计该参数下非空值的数量 int nonEmptyValueCount = paramEntries.Count(p => !string.IsNullOrEmpty(p[1])); if (nonEmptyValueCount > 1) { // 多个非空值的重复参数,触发报错 LogManager.Publish(LogTypes.Exception | LogTypes.Error, $"重复参数 {paramName} 存在多个有效值,请求内容:{decryptedRequest}"); return false; } // 仅一个非空值或全为空,属于合法情况,后续清理即可 } } // 生成清理后的请求串:每个参数保留一个实例,优先选有值的 var cleanedParams = paramPairs.GroupBy(p => p[0]) .Select(g => { // 先找有值的项,没有就取第一个空值项 var nonEmptyEntry = g.Where(p => !string.IsNullOrEmpty(p[1])).FirstOrDefault(); return nonEmptyEntry ?? g.First(); }) .Select(p => $"{p[0]}={p[1]}"); string cleanedRequest = string.Join("&", cleanedParams); // 这里可以把cleanedRequest传入后续业务逻辑 return true; } // 重写后的IsDuplicatedParam方法(如果需要单独调用该方法) private bool IsDuplicatedParam(string parameter, string decryptedRequest) { var paramPairs = decryptedRequest.Split('&') .Select(pair => pair.Split(new[] { '=' }, 2)) .Where(parts => parts.Length == 2); var paramEntries = paramPairs.Where(p => p[0] == parameter).ToList(); if (paramEntries.Count <= 1) return false; // 统计非空值的数量,超过1则返回true(触发报错) int nonEmptyCount = paramEntries.Count(p => !string.IsNullOrEmpty(p[1])); return nonEmptyCount > 1; }
逻辑说明
- 参数解析:将请求串拆分为键值对列表,避开原字符串替换方法的局限性,能准确获取每个参数的实际值
- 重复参数判定:
- 对每个参数统计出现次数,仅当出现多次时才做进一步判断
- 统计该参数下非空值的数量:数量大于1则判定为非法,触发报错;否则为合法
- 参数清理:通过分组对每个参数进行处理,优先保留有值的实例,无值则保留一个空值实例,生成符合要求的清理后请求串
内容的提问来源于stack exchange,提问作者test test
相关产品推荐
相关产品推荐

