Example #1
0
        /// <summary>
        /// Reads the content of the HTTP response as string asynchronously.
        /// </summary>
        /// <param name="httpContent">The content.</param>
        /// <param name="encoding">The encoding. You can leave this parameter null and the encoding will be
        /// automatically calculated based on the charset in the response. Also, UTF-8
        /// encoding will be used if the charset is absent from the response, is blank
        /// or contains an invalid value.</param>
        /// <returns>The string content of the response.</returns>
        /// <remarks>
        /// This method is an improvement over the built-in ReadAsStringAsync method
        /// because it can handle invalid charset returned in the response. For example
        /// you may be sending a request to an API that returns a blank charset or a
        /// mispelled one like 'utf8' instead of the correctly spelled 'utf-8'. The
        /// built-in method throws an exception if an invalid charset is specified
        /// while this method uses the UTF-8 encoding in that situation.
        ///
        /// My motivation for writing this extension method was to work around a situation
        /// where the 3rd party API I was sending requests to would sometimes return 'utf8'
        /// as the charset and an exception would be thrown when I called the ReadAsStringAsync
        /// method to get the content of the response into a string because the .Net HttpClient
        /// would attempt to determine the proper encoding to use but it would fail due to
        /// the fact that the charset was misspelled. I contacted the vendor, asking them
        /// to either omit the charset or fix the misspelling but they didn't feel the need
        /// to fix this issue because:
        /// "in some programming languages, you can use the syntax utf8 instead of utf-8".
        /// In other words, they are happy to continue using the misspelled value which is
        /// supported by "some" programming languages instead of using the properly spelled
        /// value which is supported by all programming languages.
        /// </remarks>
        /// <example>
        /// <code>
        /// var httpRequest = new HttpRequestMessage
        /// {
        ///     Method = HttpMethod.Get,
        ///     RequestUri = new Uri("https://api.vendor.com/v1/endpoint")
        /// };
        /// var httpClient = new HttpClient();
        /// var response = await httpClient.SendAsync(httpRequest, CancellationToken.None).ConfigureAwait(false);
        /// var responseContent = await response.Content.ReadAsStringAsync(null).ConfigureAwait(false);
        /// </code>
        /// </example>
        public static async Task <string> ReadAsStringAsync(this HttpContent httpContent, Encoding encoding)
        {
            var content = string.Empty;

            if (httpContent != null)
            {
                var contentStream = await httpContent.ReadAsStreamAsync().ConfigureAwait(false);

                if (encoding == null)
                {
                    encoding = httpContent.GetEncoding(Encoding.UTF8);
                }

                // This is important: we must make a copy of the response stream otherwise we would get an
                // exception on subsequent attempts to read the content of the stream
                using (var ms = Utils.MemoryStreamManager.GetStream())
                {
                    await contentStream.CopyToAsync(ms).ConfigureAwait(false);

                    ms.Position = 0;
                    using (var sr = new StreamReader(ms, encoding))
                    {
                        content = await sr.ReadToEndAsync().ConfigureAwait(false);
                    }

                    // It's important to rewind the stream
                    if (contentStream.CanSeek)
                    {
                        contentStream.Position = 0;
                    }
                }
            }

            return(content);
        }
Example #2
0
        /// <summary>
        /// Reads the content of the HTTP response as string asynchronously.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="encoding">The encoding. You can leave this parameter null and the encoding will be
        /// automatically calculated based on the charset in the response. Also, UTF-8
        /// encoding will be used if the charset is absent from the response, is blank
        /// or contains an invalid value.</param>
        /// <returns>The string content of the response</returns>
        /// <remarks>
        /// This method is an improvement over the built-in ReadAsStringAsync method
        /// because it can handle invalid charset returned in the response. For example
        /// you may be sending a request to an API that returns a blank charset or a
        /// mispelled one like 'utf8' instead of the correctly spelled 'utf-8'. The
        /// built-in method throws an exception if an invalid charset is specified
        /// while this method uses the UTF-8 encoding in that situation.
        ///
        /// My motivation for writing this extension method was to work around a situation
        /// where the 3rd party API I was sending requests to would sometimes return 'utf8'
        /// as the charset and an exception would be thrown when I called the ReadAsStringAsync
        /// method to get the content of the response into a string because the .Net HttpClient
        /// would attempt to determine the proper encoding to use but it would fail due to
        /// the fact that the charset was misspelled. I contacted the vendor, asking them
        /// to either omit the charset or fix the misspelling but they didn't feel the need
        /// to fix this issue because:
        /// "in some programming languages, you can use the syntax utf8 instead of utf-8".
        /// In other words, they are happy to continue using the misspelled value which is
        /// supported by "some" programming languages instead of using the properly spelled
        /// value which is supported by all programming languages!
        /// </remarks>
        /// <example>
        /// <code>
        /// var httpRequest = new HttpRequestMessage
        /// {
        ///     Method = HttpMethod.Get,
        ///     RequestUri = new Uri("https://api.vendor.com/v1/endpoint")
        /// };
        /// var httpClient = new HttpClient();
        /// var response = await httpClient.SendAsync(httpRequest, CancellationToken.None).ConfigureAwait(false);
        /// var responseContent = await response.Content.ReadAsStringAsync(null).ConfigureAwait(false);
        /// </code>
        /// </example>
        public static async Task <string> ReadAsStringAsync(this HttpContent content, Encoding encoding)
        {
            var responseStream = await content.ReadAsStreamAsync().ConfigureAwait(false);

            var responseContent = string.Empty;

            if (encoding == null)
            {
                encoding = content.GetEncoding(Encoding.UTF8);
            }

            // This is important: we must make a copy of the response stream otherwise we would get an
            // exception on subsequent attempts to read the content of the stream
            using (var ms = new MemoryStream())
            {
                await content.CopyToAsync(ms).ConfigureAwait(false);

                ms.Position = 0;
                using (var sr = new StreamReader(ms, encoding))
                {
                    responseContent = await sr.ReadToEndAsync().ConfigureAwait(false);
                }
            }

            return(responseContent);
        }
Example #3
0
        private async Task <string> GetBodyAsStringAndRewindAsync(HttpContent content)
        {
            try
            {
                var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);

                if (stream != null)
                {
                    if (content.IsTextContent())
                    {
                        var encoding = content.GetEncoding();
                        var str      = await stream.ReadAllTextAndRewindAsync(encoding).ConfigureAwait(false);

                        return(str.Length <= MaxLoggedBodyLength
                            ? str
                            : str.Substring(0, MaxLoggedBodyLength));
                    }
                    else
                    {
                        var bytes = await stream.ReadAllAndRewindAsync().ConfigureAwait(false);

                        return(BitConverter.ToString(bytes, 0, MaxLoggedBodyLength).Replace("-", string.Empty));
                    }
                }
            }
            catch
            {
            }

            return(null);
        }
        public static async Task <byte[]> ReadAsByteArrayAsync(this HttpContent httpContent, Encoding dstEncoding)
        {
            var encoding  = httpContent.GetEncoding();
            var byteArray = await httpContent.ReadAsByteArrayAsync().ConfigureAwait(false);

            return(encoding.Equals(dstEncoding)
                ? byteArray
                : Encoding.Convert(encoding, dstEncoding, byteArray));
        }
Example #5
0
        public static async Task <string> ReadAsStringAsync(this HttpContent content, Encoding encoding)
        {
            var responseStream = await content.ReadAsStreamAsync().ConfigureAwait(false);

            var responseContent = string.Empty;

            if (encoding == null)
            {
                encoding = content.GetEncoding(Encoding.UTF8);
            }

            using (var sr = new StreamReader(responseStream, encoding))
            {
                responseContent = await sr.ReadToEndAsync().ConfigureAwait(false);
            }

            return(responseContent);
        }