/// <summary>
 /// Initializes a new instance of ViddlerRequestException class.
 /// </summary>
 internal ViddlerRequestException(ViddlerResponseError error, Exception innerException)
   : base(string.Concat(error.Code, " - ", error.Description, ": ", error.Details), innerException)
 {
   this.code = error.Code;
   this.details = error.Details;
   this.description = error.Description;
 }
 /// <summary>
 /// Initializes a new instance of ViddlerRequestException class.
 /// </summary>
 internal ViddlerRequestException(ViddlerResponseError error, Exception innerException)
     : base(string.Concat(error.Code, " - ", error.Description, ": ", error.Details), innerException)
 {
     this.code        = error.Code;
     this.details     = error.Details;
     this.description = error.Description;
 }
        /// <summary>
        /// Handles a web response from the remote server.
        /// </summary>
        private static DataType HandleHttpResponse <ContractType, DataType>(HttpWebRequest request, ViddlerMethodAttribute methodAttribute, string dumpPath)
        {
            DataType responseObject = default(DataType);

            using (WebResponse response = request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        int    count;
                        byte[] buffer = new byte[1024];
                        do
                        {
                            count = responseStream.Read(buffer, 0, 1024);
                            stream.Write(buffer, 0, count);
                        } while (count > 0); // copy response stream to "seek-enabled" stream

                        if (!string.IsNullOrEmpty(dumpPath))
                        {
                            ViddlerService.DumpResposeToFile(dumpPath, stream, methodAttribute.MethodName, request.RequestUri.ToString());
                        }

                        stream.Position = 0;
                        string            messageType    = string.Empty;
                        XmlReaderSettings readerSettings = new XmlReaderSettings();
                        readerSettings.CloseInput     = false;
                        readerSettings.IgnoreComments = true;
                        readerSettings.IgnoreProcessingInstructions = true;
                        using (XmlReader reader = XmlReader.Create(stream, readerSettings))
                        {
                            if (reader.MoveToContent() == XmlNodeType.Element)
                            {
                                messageType = reader.LocalName;
                            }
                        }

                        stream.Position = 0;
                        if (messageType.Equals(methodAttribute.ElementName, StringComparison.Ordinal))
                        {
                            try
                            {
                                XmlSerializer serializer = new XmlSerializer(typeof(ContractType));
                                responseObject = (DataType)serializer.Deserialize(stream);
                            }
                            catch (Exception exception)
                            {
                                if (exception.InnerException != null && exception.InnerException.GetType() == typeof(System.FormatException)) // XmlSerializer has problems with parsing primitive types - removing empty nodes, which are deserialized to properties of primitive type
                                {
                                    stream.Position = 0;
                                    Dictionary <string, Type> nodesToCheck = ViddlerHelper.GetExpectedPrimitiveTypeNodes(typeof(ContractType));
                                    XmlDocument responseXml = new XmlDocument();
                                    responseXml.PreserveWhitespace = true;
                                    responseXml.Load(stream);

                                    foreach (string node in nodesToCheck.Keys)
                                    {
                                        foreach (XmlNode xmlNode in responseXml.SelectNodes(node))
                                        {
                                            if (string.IsNullOrEmpty(xmlNode.InnerText.Trim()))
                                            {
                                                xmlNode.ParentNode.RemoveChild(xmlNode);
                                            }
                                        }
                                    }

                                    using (MemoryStream xmlStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseXml.OuterXml)))
                                    {
                                        XmlSerializer serializer = new XmlSerializer(typeof(ContractType));
                                        responseObject = (DataType)serializer.Deserialize(xmlStream);
                                    }
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                        else if (messageType.Equals("error", StringComparison.Ordinal))
                        {
                            XmlSerializer        serializer  = new XmlSerializer(typeof(ViddlerResponseError));
                            ViddlerResponseError errorObject = (ViddlerResponseError)serializer.Deserialize(stream);
                            throw new ViddlerRequestException(errorObject, null);
                        }
                        else
                        {
                            XmlDocument responseXml = new XmlDocument();
                            responseXml.PreserveWhitespace = true;
                            responseXml.Load(stream);
                            throw new System.InvalidOperationException(responseXml.OuterXml);
                        }
                    }
                }
            }

            return(responseObject);
        }