0

I'm trying to send a simple HTTP POST request to a web service and read the response. I need to do this in a .NET project but the call fails all the time. I tested to call the same web service in Java and it went with no problems at all.

Here's my code in 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);
        }

The code fails when I call httpRequest.Result. The ultimate exception message is the following:

"Unable to read data from the transport connection: the connection was closed."

However, when I try the same in Java it works perfectly. Here's my Java code:

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

For the C# part I tested other http-related objects in .NET: HttpWebRequest and WebClient, only to get the same exception message.

I'm suspecting that the .NET objects add some type of header or a default setting which must be disabled, but I don't know what it is.

FYI:
- the Java code works even if I remove all the calls to setRequestProperty, so the code passes without explicitly setting "User-Agent", "Accept-Language" etc. - the web service is set up to close the connection immediately after the communication is over, i.e. there's no keep-alive available. I seem to recall that this feature is "disliked" by .NET web client objects, but I wouldn't bet my life on it. - you'll notice that I set ExpectContinue to false in C# but not in Java. In Java it's apparently no necessary whereas I had to switch this off in other C# projects to make the call work. I tested to set it to true without any difference in the result.

Any suggestions are welcome. I have no control over the web service settings so please don't suggest anything that requires such a change.

Thanks, Andras

Andras
  • 171
  • 3
  • 16

3 Answers3

0

I would suggest not adding the connection header. First of all, with the HttpClient if you wanted to ask the server to close the connection after the request you would do

   httpClient.DefaultRequestHeaders.ConnectionClose = true;

Http 1.1 uses keep-alive by default, so there is no need to send the header. If the server returns Connection: close then the client should handle that just fine.

HttpClient does get a bit upset when you start messing with headers that it wants to have control over.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • Thanks for your suggestion. I removed all header declarations and added the connectionclose = true bit but I'm still getting the same exception unfortunately. – Andras Oct 07 '13 at 06:56
0

You may want to try Fiddler Web Debugging Proxy. It may help to find the difference in HTTP traffic (fiddler2.com).

mp31415
  • 6,531
  • 1
  • 44
  • 34
-1

try this

        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());
        }
        }
Aravind
  • 1,521
  • 2
  • 12
  • 23