SSH中Curl发起SOAP请求正常,C# Web请求返回404错误
在Linux SSH环境下通过Curl发起SOAP请求可正常获取预期结果,执行命令:curl --location 'https://DOMAIN_URI' --header 'Content-Type: text/xml' --data 'SOAP body here'
但将C# Web请求代码部署至Docker环境后,收到404错误:
System.Net.WebException: The remote server returned an error: (404) Not Found.
at System.Net.HttpWebRequest.GetResponse()
对应的C#代码如下:
try { // Create the web request HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https url"); request.Method = "POST"; request.ContentType = "text/xml"; // Set the SOAP envelope as the request body string soapEnvelope = @"soap body here"; byte[] bodyBytes = Encoding.UTF8.GetBytes(soapEnvelope); request.ContentLength = bodyBytes.Length; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(bodyBytes, 0, bodyBytes.Length); } string responseText = ""; // Make the request and get the response using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (StreamReader responseReader = new StreamReader(response.GetResponseStream())) { responseText = responseReader.ReadToEnd(); Console.WriteLine(responseText); } } return this.StatusCode(StatusCodes.Status200OK, new { data = new { message = responseText, url = _url } }); } catch (Exception ex) { return this.StatusCode(StatusCodes.Status500InternalServerError, new { data = new { message = ex.ToString(), url = _url } }); }
1. 验证请求URL一致性
确认C#代码中WebRequest.Create("https url")的地址与curl命令中的https://DOMAIN_URI完全匹配,包括路径、大小写、附加参数等。Docker环境中可能存在配置变量错误,导致URL拼接异常。
2. 开启自动重定向支持
curl的--location参数会自动跟随3xx重定向,但HttpWebRequest默认不处理重定向。若目标服务器返回重定向,C#代码会直接返回404。解决方法:
request.AllowAutoRedirect = true;
3. 检查Docker容器网络连通性
Docker容器可能处于自定义网络,无法解析目标域名或访问目标端口。可在容器内部执行curl命令测试:
docker exec -it [容器ID/名称] curl --location 'https://DOMAIN_URI' --header 'Content-Type: text/xml' --data 'SOAP body here'
若容器内curl也失败,需排查容器网络配置、主机防火墙规则或代理设置。
4. 核对SOAP请求体格式与编码
- 确保C#代码中
Encoding.UTF8.GetBytes(soapEnvelope)的编码与curl一致,避免特殊字符编码差异。 - 将curl的SOAP请求体保存为文件,在C#中直接读取文件内容作为请求体,消除手动书写的换行、空格等格式差异。
5. 配置代理(若需)
若Linux主机通过代理访问目标服务器,Docker容器默认不会继承代理配置。可通过两种方式解决:
- 容器启动时添加代理环境变量:
docker run -e HTTP_PROXY=http://proxy-host:port -e HTTPS_PROXY=http://proxy-host:port [镜像名] - 在C#代码中设置代理:
request.Proxy = new WebProxy("http://proxy-host:port");
6. 替换为HttpClient API
HttpWebRequest为旧版API,HttpClient默认支持重定向,兼容性更优。可尝试替换代码:
using (HttpClient client = new HttpClient()) { StringContent content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml"); HttpResponseMessage response = await client.PostAsync(_url, content); response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); return this.StatusCode(StatusCodes.Status200OK, new { data = new { message = responseText, url = _url } }); }
内容的提问来源于stack exchange,提问作者Salman Rafique

