0

単純な 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 サービスの設定を制御できないため、そのような変更が必要なことは何も提案しないでください。

ありがとう、アンドラス

4

3 に答える 3

0

Fiddler Web Debugging Proxy を試すことをお勧めします。HTTP トラフィック ( fiddler2.com )の違いを見つけるのに役立つ場合があります。

于 2013-11-28T17:31:04.313 に答える
0

接続ヘッダーを追加しないことをお勧めします。まず、リクエストの後にサーバーに接続を閉じるように依頼したい場合は、HttpClient を使用します。

   httpClient.DefaultRequestHeaders.ConnectionClose = true;

HTTP 1.1 はデフォルトで keep-alive を使用するため、ヘッダーを送信する必要はありません。サーバーが戻ったConnection: close場合、クライアントはそれをうまく処理する必要があります。

HttpClient は、制御したいヘッダーをいじり始めると、少し動揺します。

于 2013-10-05T05:35:22.193 に答える
-1

これを試して

        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());
        }
        }
于 2013-10-22T06:28:25.103 に答える