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

循环调用外部Web API首次成功后续报404,换RestSharp遇Forbidden

问题分析与解决方案

原HttpWebRequest代码二次调用404的可能原因

  • 资源未彻底释放:原代码手动关闭流和响应,但未利用using语句处理HttpWebRequest/HttpWebResponse这类实现IDisposable的对象,循环中可能出现连接池耗尽或资源泄漏,导致服务器无法处理后续请求返回404。
  • 请求参数意外变更:检查foreach循环中apiUrl是否被修改,或是XML内容包含的动态参数(如路由标识)错误,导致API路由匹配失败。
  • 服务器限流/拦截:部分API会限制同一客户端的请求频率,首次请求后后续请求被临时拦截,用404作为伪装的限流提示。

RestSharp报Forbidden的可能原因

  • 认证编码不匹配:原代码用ISO-8859-1编码生成Basic认证字符串,RestSharp默认用UTF-8,导致认证信息不一致被服务器拒绝。
  • 请求头/内容编码遗漏:原代码明确设置了ContentType和ASCII编码的XML内容,迁移到RestSharp时可能未同步这些设置,导致服务器解析失败。

修正后的代码示例

改进版HttpWebRequest(用using确保资源释放)

foreach (var item in yourItems)
{
    string xmlFileName = Path.GetFileName(xmlDocument.BaseURI);
    string response = string.Empty;

    using (HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(apiUrl))
    {
        // 按原逻辑生成Basic认证头
        string basicAuth = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes($"{apiUrlUsername}:{apiUrlUserPassword}"));
        httpWebRequest.Headers.Add("Authorization", $"Basic {basicAuth}");

        httpWebRequest.Method = "POST";
        httpWebRequest.ContentType = apiContentType;

        byte[] requestBytes = Encoding.ASCII.GetBytes(xmlDocument.InnerXml);
        httpWebRequest.ContentLength = requestBytes.Length;

        using (Stream requestStream = httpWebRequest.GetRequestStream())
        {
            requestStream.Write(requestBytes, 0, requestBytes.Length);
        }

        using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
        using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.Default))
        {
            response = streamReader.ReadToEnd();
        }

        // 处理返回结果
    }
}

匹配原逻辑的RestSharp实现

foreach (var item in yourItems)
{
    var client = new RestClient(apiUrl);
    var request = new RestRequest(Method.POST);

    // 沿用ISO-8859-1编码生成认证头
    var authBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"{apiUrlUsername}:{apiUrlUserPassword}");
    request.AddHeader("Authorization", $"Basic {Convert.ToBase64String(authBytes)}");

    // 同步原代码的ContentType设置
    request.AddHeader("Content-Type", apiContentType);

    // 用ASCII编码发送XML内容
    request.AddParameter(apiContentType, xmlDocument.InnerXml, ParameterType.RequestBody, Encoding.ASCII);

    IRestResponse response = client.Execute(request);

    // 处理返回结果
}

额外排查建议

  • 抓包对比首次和二次请求的完整报文,确认URL、请求头、body内容是否存在差异。
  • 检查原代码中获取的xmlFileName是否需要作为请求参数/头传递给API(当前代码仅获取未使用)。
  • 联系API提供方,确认是否存在请求频率限制、会话绑定等机制导致后续请求被拒绝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:20:32