I am facing an issue with the C# HttpClient's PostAsync method. I am calling an API which is on HTTPS SSL and things are working fine until I deployed my code on to a server which has the following in the web.config
var response = await Client.PostAsync(path, requestObject);
response.EnsureSuccessStatusCode();
string strResponse = response.Content.ReadAsStringAsync().Result;
The API being called is on HTTPS and the certificate is trusted on my machine.
<httpRuntime maxRequestLength="40960" **targetFramework="4.8" **enableVersionHeader="false" />
My local environment doesn't have the targetFramework in the web.config. The API call only works if I remove the TargetFramework attribute. After adding the attribute back, there seems to be no errors or response, the execution hangs for 5 minutes. There is no exception or error, nothing in the event viewer.
I have tried a lot of things like setting the TLS
Security.Transport.SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12;
and
System.Net.ServicePointManager.SecurityProtocol |=
SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
But nothing seems to work. We need the targetframework attribute and need this api call to work. What is the TargetFramework attribute adding in terms of configuration which is leading to api call failing/hanging ?
CodePudding user response:
targetFramework
controls the server-side "quirks mode". One of those "quirks" is which SynchronizationContext
to use. Without the targetFramework
setting, ASP.NET uses the LegacyAspNetSynchronizationContext
, which doesn't work correctly with async
and await
. With the targetFramework
setting, ASP.NET uses AspNetSynchronizationContext
, which does work with async
and await
.
If your code is blocking on asynchronous code, then it's possible that the old/legacy SynchronizationContext
will not cause a deadlock when it actually should. Note that removing the targetFramework
is not the correct solution, since the old/legacy SynchronizationContext
shouldn't be used with async
/await
at all. The proper solution is to remove the blocking so that no deadlock can occur with the new SynchronizationContext
.