我正在尝试向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”等的情况下通过。
- 设置Web服务以在通信结束后立即关闭连接,即没有保持活动可用。我似乎记得.NET Web客户端对象“不喜欢”这个功能,但我不打赌我的生活。
- 你会注意到我在C#中将ExpectContinue设置为false,而在Java中则没有。在Java中,显然没有必要,而我必须在其他C#项目中关闭它以使调用工作。我测试将其设置为true而结果没有任何差异。
欢迎任何建议。我无法控制Web服务设置,因此请不要提出任何需要进行此类更改的建议。
谢谢, 安德拉斯
答案 0 :(得分:0)
我建议不要添加连接头。首先,如果您想要请求服务器在请求后关闭连接,请使用HttpClient
httpClient.DefaultRequestHeaders.ConnectionClose = true;
Http 1.1默认使用keep-alive,因此无需发送标头。如果服务器返回Connection: close
,则客户端应该处理该问题。
当您开始弄乱它想要控制的标题时,HttpClient确实有点不高兴。
答案 1 :(得分:0)
您可能想尝试Fiddler Web调试代理。找到HTTP流量(fiddler2.com)的差异可能会有所帮助。
答案 2 :(得分:-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());
}
}