0

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 ?

i123iu
  • 19
  • 1
  • 4
Nitin A
  • 3
  • 2
  • Why don't you enable that also on your dev machine and take a closer look with the debugger what is happening? It sounds weird to me telling the system via the config to use some sort of compatibility mode when you haven't developed in that mode. – Ralf Dec 13 '22 at 17:26
  • Have you checked https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/retargeting/4.0-4.8#networking – Stephen Cleary Dec 13 '22 at 17:42
  • @Ralf I have debugged and the execution stops at when invoking the post api call. I am not able to debug the real issue. No exception is thrown, no error is shown and breakpoint in next line never gets hit. – Nitin A Dec 13 '22 at 18:09
  • @NitinA: Are you [blocking on asynchronous code](https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)? – Stephen Cleary Dec 13 '22 at 18:44
  • @StephenCleary No, I don't think so, since it's works 10/10 times when I remove the target framework attribute. – Nitin A Dec 14 '22 at 00:49
  • @NitinA: The target framework attribute turns on and off server-side quirks mode, which changes the `SynchronizationContext` used for ASP.NET requests, which is part of what causes sync-over-async deadlocks. So it *could* be related to the issue you're seeing. – Stephen Cleary Dec 14 '22 at 01:40
  • @StephenCleary, Thank you for the wonderful suggestion. I have realized that the issue is due to a deadlock. I have made the changes and it works now. Please elaborate your suggestion as an answer, would be happy to mark it as resolved. – Nitin A Dec 14 '22 at 05:15

1 Answers1

0

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.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810