/// <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); }
/// <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); }
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)); }
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); }