【问题标题】:Http POST request succeeds in Java but fails in C#Http POST 请求在 Java 中成功,但在 C# 中失败
【发布时间】:2013-10-04 13:14:33
【问题描述】:

我正在尝试向 Web 服务发送一个简单的 HTTP POST 请求并读取响应。我需要在 .NET 项目中执行此操作,但调用始终失败。我测试了在 Java 中调用相同的 Web 服务,它完全没有问题。

这是我的 C# 代码:

HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, "web service URI");


        string json = "some json input";
        requestMessage.Content = new StringContent(json, Encoding.UTF8, "application/json");            
        HttpClient httpClient = new HttpClient();       
        httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
        httpClient.DefaultRequestHeaders.Add("Accept-Language", "en");
        httpClient.DefaultRequestHeaders.Add("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");                                                                                                                    
        httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
        httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
        httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
        httpClient.DefaultRequestHeaders.ExpectContinue = false;

        try
        {               
            Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead
                , CancellationToken.None);

            HttpResponseMessage httpResponse = httpRequest.Result;
            HttpStatusCode statusCode = httpResponse.StatusCode;
            HttpContent responseContent = httpResponse.Content;
            if (responseContent != null)
            {
                Task<string> stringContentTask = responseContent.ReadAsStringAsync();
                string stringContent = stringContentTask.Result;
                return stringContent;
            }
            else
            {
                throw new Exception("Response content is null.");
            }
        }
        catch (AggregateException ae)
        {
            List<Exception> innerExceptions = ae.InnerExceptions.ToList();
            StringBuilder sb = new StringBuilder();
            foreach (Exception e in innerExceptions)
            {
                sb.Append(e.Message).Append(Environment.NewLine);
                if (e.InnerException != null)
                {
                    sb.Append(e.InnerException.Message).Append(Environment.NewLine);
                }
            }
            Console.WriteLine(sb.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

调用 httpRequest.Result 时代码失败。最终的异常消息如下:

“无法从传输连接中读取数据:连接已关闭。”

但是,当我在 Java 中尝试相同的方法时,它可以完美运行。这是我的 Java 代码:

String url = "web service URI";
        URL obj = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) obj.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
        connection.setRequestProperty("Accept-Language", "en");
        connection.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");
        connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Cache-Control", "no-cache");
        connection.setRequestProperty("Connection", "Close");
        String content = "some json";
        connection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
        wr.writeBytes(content);
        wr.flush();
        wr.close();

        int responseCode = connection.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + content);
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();

        while ((inputLine = in.readLine()) != null)
        {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());

对于 C# 部分,我在 .NET 中测试了其他与 http 相关的对象:HttpWebRequest 和 WebClient,只是为了得到相同的异常消息。

我怀疑 .NET 对象添加了某种类型的标头或必须禁用的默认设置,但我不知道它是什么。

仅供参考:
- 即使我删除了对 setRequestProperty 的所有调用,Java 代码仍然有效,因此代码通过而无需显式设置“User-Agent”、“Accept-Language”等。 - 网络服务设置为在通信结束后立即关闭连接,即没有可用的保持活动状态。我似乎记得.NET Web 客户端对象“不喜欢”此功能,但我不会赌上我的生命。 - 你会注意到我在 C# 中将 ExpectContinue 设置为 false,但在 Java 中没有。在 Java 中,这显然没有必要,而我必须在其他 C# 项目中关闭它才能使调用正常工作。我测试将其设置为 true,结果没有任何差异。

欢迎提出任何建议。我无法控制网络服务设置,因此请不要提出任何需要进行此类更改的建议。

谢谢, 安德拉斯

【问题讨论】:

  • 你看我的回答了吗
  • 尝试没有缓存控制头的相同代码

标签: c# java .net webrequest dotnet-httpclient


【解决方案1】:

我建议不要添加连接头。首先,如果您想在请求后要求服务器关闭连接,请使用 HttpClient

   httpClient.DefaultRequestHeaders.ConnectionClose = true;

Http 1.1 默认使用keep-alive,所以不需要发送header。如果服务器返回Connection: close,那么客户端应该处理得很好。

当您开始弄乱它想要控制的标头时,HttpClient 确实会有点不高兴。

【讨论】:

  • 感谢您的建议。我删除了所有标头声明并添加了 connectionclose = true 位,但不幸的是我仍然遇到相同的异常。
【解决方案2】:

您可能想尝试 Fiddler Web 调试代理。它可能有助于找出 HTTP 流量的差异 (fiddler2.com)。

【讨论】:

    【解决方案3】:

    试试这个

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("Your URL");
            byte[] data = Encoding.UTF8.GetBytes("Post Input");
            request.Method = "POST";
            request.Accept = "application/json"; //you can set application/xml
            request.ContentType = "application/json";// you can set application/xml
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(data, 0, data.Length);
            dataStream.Close();
            HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
            StreamReader result = new StreamReader(resp.GetResponseStream());
            if( result !=null)
            {
            if(!string.IsNullorEmpty(result.ReadToEnd().ToString()))
            {
              MessageBox.Show(result.ReadToEnd().ToString());
            }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      相关资源
      最近更新 更多