dotnet / dotnet/docs

Usability issues in HttpClient caused by inadequate documentation

Open
#37,999 1 comment 0 reactions 0 assignees View on GitHub
:watch: Not Triaged networking/subsvc
Dominant language
No language data
Stars
4.8k
Forks
6.1k
Avg merge
19h 10m
Merged PRs (30d)
268

Description

**Issue description**

Ref: https://github.com/dotnet/runtime/issues/94471 All components were analyzed and found to be documentation issues.

1) It's not clear how to abort generating the request body in the middle (due to a thrown exception while generating content). That is, bailing out of HttpContent.SerializeToStreamAsync() needs proper documentation for how to do it.

The answer is "calle doesn't own the stream; to abort generation, don't close stream and throw an exception". There's some debate as to whether or not this is the natural way to do it, but it definitely wasn't clear to _me_ that was how to do it.

2) When calling HttpResponse.Content.ReadAsStreamAsync() we have a confusing bit in the documentation. The current behavior of `await (await HttpClient.PostAsync()).Content.ReadAsStreamAsync())` is to spool up the entire response into a memory stream (at least most of the time--it's actually not clear if there's cases where it won't). On receiving an answer for how to get it to give the caller the actual stream and reading the documentation with the answer in mind; I now believe the following: The behavior of `await (await HttpClient.PostAsync(string, HttpContent, CancellationToken)).Content.ReadAsStreamAsync())` is unspecified. The behavior of `await (await HttpClient.SendAsync(string, HttpContent, CancellationToken)).Content.ReadAsStreamAsync())` is unspecified. `await (await HttpClient.SendAsync(string, HttpContent, HttpCompletionOption, CancellationToken)).Content.ReadAsStreamAsync())` is specified.

The main problem here is the lack of discoverability. It is not discoverable when trying to call `GetAsync()` or `PostAsync()` on either a multi-GB file or an infinite event source that caller needs to switch to the four argument version of `SendAsync()`. And the Visual Studio IDE actually makes discovery harder in this case due to its habit of masking the four argument version `SendAsync()` with the three argument version.

I had an idea of how to fix this by annotating `.ReadAsStreamAsync()` to mention `SendAsync()` and `HttpCompletionOption`; however I was told this was bad.

3) `HttpResponse.Content.ReadAsStringAsync() ` only does ";charset" header inspection and BOM detection. If there's no BOM it will believe its input is UTF-8 even if it's nuts as UTF-8. This is surprising behavior as most people are used to everything but the meanest editors doing some basic differentiation between ANSI, UTF-16, and UTF-8 character sets even without a BOM. The lack of actual character set detection should be documented.

Use case: Third party server generates JSON and returns it as "application/json" (which is correct for JSON in any allowed encoding); It looks like you can do `HttpResponse.Content.ReadAsStringAsync() ` _however this doesn't actually work_ unless the server can be relied on to return JSON in UTF-8. The JSON spec says no BOM; so the programmer has to to do UTF-16/UTF-8 detection. Calling `.ReadAsStringAsync()` and sending the result to `Newtonsoft.Json` (or System.Text.Encoding.UTF8.GetBytes()` followed by `System.Text.Json`) is a latent bug. Thus the programmer needs to know this doesn't work.

**Target framework**

- [X] .NET Core
- [X] .NET Framework
- [X] .NET Standard

(all versions)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.