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