Ok made some progress. Seems to work locally if I do:
....return new EmptyResult();
because I think the server is objecting to adding a status code to a stream already written bytes to. Still have no idea why the Azure web server never raised this objection - it is only arises locally.
.Net Core Web Api. Can't Write Bytes to the Response Stream
I coded and maintained a .Net Core web api for over a year now. After a year of success, I now get an error when running the web api locally at https://localhost:42123 (but no such error on the deployed version in Azure App Services). I need it to continue to work locally because I have always relied on local debugging.
The error seen locally is: "Error while copying content to a stream. Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
After an entire day of trying suggestions on the internet (various combinations of TLS settings, Keep-Alive, ConnectionLimit, HttpVersion, ServicePointManager.Expect100Continue, etc), I finally pinpointed two lines of code triggering the error. The API-response is returning basically three items to the consumer:
...StatusCode <---- no problem here
...ReasonPhrase <---- no problem here
...Content (Body) <---- triggers the error
For the Body, it is manually writing out bytes to the response stream via 2 lines of code shown below. Commenting out those 2 lines clears the error. I don't see any C# exception happening there - the next line of code executes just fine.
Why did those 2 line of code suddenly stop working locally after a year? And why does it continue to work fine in Azure App Services?
public static IActionResult GoodRequest(ControllerBase This, int statusCode, string strReasonPhrase, string strContent) {
HttpStatusCode httpStatusCode = (HttpStatusCode)statusCode;
strReasonPhrase = $"{httpStatusCode}. {strReasonPhrase}";
if (strReasonPhrase.Length > 510) strReasonPhrase = strReasonPhrase.Substring(0, 510);
This.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = strReasonPhrase;
This.HttpContext.Features.Get<IHttpResponseFeature>().StatusCode = statusCode;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strContent);
This.HttpContext.Features.Get<IHttpResponseBodyFeature>().Writer.WriteAsync(bytes).GetAwaiter().GetResult();
return new StatusCodeResult(statusCode);
}
BTW, I am running the queries from a .Net 4.72 winforms application, via httpClient and Azure AD token. Even during local debugging, I am using an AD token to authenticate.
-
JAL 591 Reputation points
2021-09-30T19:12:59.067+00:00