HTTPWebResponse Response string is truncated

2019-07-06 02:02发布

问题:

App is talking to a REST service. Fiddler shows full good XML response coming in as the Apps response The App is in French Polynesia and an identical copy in NZ works so the prime suspect seemed encoding but we have checked that out and came up empty handed.

Looking at the output string (UTF8 encoding) from the stream reader you can see where it has been truncated. It is in an innocuous piece of xml. The downstream error on an XmlDocument object claims to have an encountered an unexpected end of file while loading the string into an XML Document object which is fair enough.

The truncation point is
ns6:sts-krn>1&

which is part of ns6:sts-krn>1</ns6:sts-krn><

Is there any size limitation on the response string or some other parameter that we should check. I am all out of ideas. Code Supplied as requested.

Stream streamResponse = response.GetResponseStream();
StringBuilder sb = new StringBuilder();

Encoding encode = Encoding.GetEncoding("utf-8");
if (streamResponse != null)
{
    StreamReader readStream = new StreamReader(streamResponse, encode);
    while (readStream.Peek() >= 0)
    {
        sb.Append((char)readStream.Read());
    }
    streamResponse.Close();
}

回答1:

You need to be using using blocks:

using (WebResponse response = request.GetResponse())
{
    using (Stream streamResponse = response.GetResponseStream())
    {
        StringBuilder sb = new StringBuilder();

        if (streamResponse != null)
        {
            using (StreamReader readStream = new StreamReader(streamResponse, Encoding.UTF8))
            {
                sb.Append(readStream.ReadToEnd());
            }
        }
    }
 }

This will ensure that your WebResponse, Stream, and StreamReader all get cleaned up, regardless of whether there are any exceptions.


The reasoning that led me to think about using blocks was:

  1. Some operation was not completed
  2. There were no try/catch blocks hiding exceptions, so if the operation wasn't completed due to exceptions, we would know about it.
  3. There were objects which implement IDisposable which were not in using blocks

Conclusion: try implementing the using blocks to see if disposing the objects will cause the operation to complete.

I added this because the reasoning is actually quite general. The same reasoning works for "my mail message doesn't get sent for two minutes". In that case, the operation which isn't completed is "send email" and the instances are the SmtpClient and MailMessage objects.



回答2:

An easier way to do this would be:

string responseString;
using (StreamReader readStream = new StreamReader(streamResponse, encode))
{
    responseString = readStream.ReadToEnd();
}

For debugging, I would suggest writing that response stream to a file so that you can see exactly what was read. In addition, you might consider using a single byte encoding (like ISO-8859-1) to read the data and write to the file.

You should check the response.ContentType property to see if some other text encoding is used.



标签: c# http