簡體   English   中英

Http POST請求在Java中成功,但在C#中失敗

[英]Http POST request succeeds in Java but fails in C#

我正在嘗試將簡單的HTTP POST請求發送到Web服務並讀取響應。 我需要在.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”等。-設置了Web服務以在通信后立即關閉連接結束后,即有沒有保活可用。 我似乎還記得,.NET Web客戶端對象“不喜歡”此功能,但我不會為此付出生命。 -您會注意到,我在C#中將ExpectContinue設置為false,而在Java中則沒有。 在Java中,顯然沒有必要,而我必須在其他C#項目中將其關閉才能使調用正常進行。 我測試,它設置為true,沒有結果的任何差異。

歡迎任何建議。 我無法控制Web服務設置,因此請不要提出任何需要進行此類更改的建議。

謝謝,安德拉斯

我建議不要添加連接頭。 首先,使用HttpClient,如果您想在請求后要求服務器關閉連接,則可以執行此操作

   httpClient.DefaultRequestHeaders.ConnectionClose = true;

Http 1.1默認情況下使用保持活動狀態,因此無需發送標頭。 如果服務器返回Connection: close則客戶端應該可以正常處理。

當您開始混淆要控制的標頭時,HttpClient確實會感到不高興。

您可能要嘗試Fiddler Web調試代理。 找到HTTP流量( fiddler2.com )的差異可能會有所幫助。

嘗試這個

        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());
        }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM