views:

147

answers:

3

Hello,

Our c#.net software connects to an online app to deal with accounts and a shop. It does this using HttpWebRequest and HttpWebResponse.

An example of this interaction, and one area where the exception in the title has come from is:

var request = HttpWebRequest.Create(onlineApp + string.Format("isvalid.ashx?username={0}&password={1}", HttpUtility.UrlEncode(username), HttpUtility.UrlEncode(password))) as HttpWebRequest;
            request.Method = "GET";
            using (var response = request.GetResponse() as HttpWebResponse)
            using (var ms = new MemoryStream())
            {
                var responseStream = response.GetResponseStream();
                byte[] buffer = new byte[4096];
                int read;
                do
                {
                    read = responseStream.Read(buffer, 0, buffer.Length);
                    ms.Write(buffer, 0, read);
                } while (read > 0);
                ms.Position = 0;
                return Convert.ToBoolean(Encoding.ASCII.GetString(ms.ToArray()));
            }

The online app will respond either 'true' or 'false'. In all our testing it gets one of these values, but for a couple of customers (out of hundreds) we get this exception System.FormatException: String was not recognized as a valid Boolean Which sounds like the response is being garbled by something. If we ask them to go to the online app in their web browser, they see the correct response. The clients are usually on school networks which can be fairly restrictive and often under proxy servers, but most cope fine once they've put the proxy details in or added a firewall exception. Is there something that could be messing up the response from the server, or is something wrong with our code?

+1  A: 

Indeed, it's possible that the return result is somehow different.

Is there any particular reason you are doing the reasonably elaborate method of reading the repsonse there? Why not:

string data;

using(HttpWebResponse response = request.GetResponse() as HttpWebResponse){
    StreamReader str = new StreamReader(response.GetResponseStream());
    data = str.ReadToEnd();
    str.Close();
}

string cleanResult = data.Trim().ToLower();

// log this

return Convert.ToBoolean(cleanResult);
Noon Silk
I would have to ask the original coder. When I looked over it originally it seemed to do the job so I didn't bother altering it. Would the method used to get the data actually affect whether it can be parsed though?
Septih
@Septh Not really, no. It's just more prone to errors, I suspect the problem is probably something to do with the connection only receiving a component of the data, or modified data. I'd add logging, and go from there.
Noon Silk
+1  A: 

First thing to note is I would definitely use something like:

bool myBool = false;
Boolean.TryParse(Encoding.ASCII.GetString(ms.ToArray()), myBool);
return myBool;
Justin Wignall
A: 

It's not some localisation issue is it? It's expecting the Swahili version of 'true', and getting confused. Are all the sites in one country, with the same language, etc?

I'd add logging, as suggested by others, and see what results you're seeing.

I'd also lean towards changing the code as silky suggested, though with a few further changes from me (code 'smell' issues, IMO); Use using around the stream reader, as well as the response.

Also, I don't think the use of as is appropriate in this instance. If the Response can't be cast to HttpWebResponse (which, admittedly is unlikely, but still) you'll get a NullRef exception on the response.GetResponseStream() bit which is both a vague error, and you've lost the original line number. Using (HttpWebResponse)request.GetResponse() will give you a more correct error, and the correct line number of the actual error.

Gareth Wilson