skip to Main Content

I am doing Async and Await with C# ASP.Net MVC, with Target .Net Framework 4.8 using Visual Studio 2022. So no matter what, I always get an exception when I call httpClient.PostAsync(...). I can call httpClient.PostAsync(...).ConfigureAwait(false) which doesn’t give me an immediate exception and my code after proceeds normally, but I still get an exception by the last closing bracket of my method.

So first, I am making httpClient a private static variable in my class, and I think this is the recommended practice:

private static readonly HttpClient httpClient = new HttpClient();

Here is the code where I call httpClient.PostAsync(...) but I don’t call ConfigureAwait(false) and this gives me an immediate exception in the Visual Studio 2022 debugger and I never make it to the end curly bracket of my method (I simplified the code a little):

private async Task MyMethod(string json, Dictionary<string, string> headerDictionary)
{
  string accessToken = GetAccessToken();


  string webhookID = WebConfigurationManager.AppSettings["PayPalWebhookID"];
  var paypalVerifyRequestJsonString = ... ...;

  string payPalServHref = WebConfigurationManager.AppSettings["PayPalV2ServHref"];

  httpClient.DefaultRequestHeaders.Clear();
  httpClient.DefaultRequestHeaders.Add("authorization", "Bearer " + accessToken);     
  var content = new StringContent(paypalVerifyRequestJsonString, Encoding.UTF8, "application/json");

  // if I return here, there is no exception
  //return;

  var resultResponse = await httpClient.PostAsync(payPalServHref + "/v1/notifications/verify-webhook-signature", content);

  // the end curly bracket of this method (the } below) is never reached
}

An exception is immediately thrown when I call httpClient.PostAsync(...):

enter image description here

Now I just change httpClient.PostAsync(...) to httpClient.PostAsync(...).ConfigureAwait(false) and my code proceeds normally when I debug it, but an exception is always thrown by the end curly bracket of my method (again, I simplified the code a little):

private async Task MyMethod(string json, Dictionary<string, string> headerDictionary)
{
  string accessToken = GetAccessToken();


  string webhookID = WebConfigurationManager.AppSettings["PayPalWebhookID"];
  var paypalVerifyRequestJsonString = ... ...;

  string payPalServHref = WebConfigurationManager.AppSettings["PayPalV2ServHref"];

  httpClient.DefaultRequestHeaders.Clear();
  httpClient.DefaultRequestHeaders.Add("authorization", "Bearer " + accessToken);     
  var content = new StringContent(paypalVerifyRequestJsonString, Encoding.UTF8, "application/json");

  // if I return here, there is no exception
  //return;

  var resultResponse = await httpClient.PostAsync(payPalServHref + "/v1/notifications/verify-webhook-signature", content).ConfigureAwait(false);

  // lines after httpClient.PostAsync(...).ConfigureAwait(false); are reached and I can debug it, but there will always be an exception 
  // thrown by the end curly bracket below (the } below) 

  // if I undo this comment for return, the return statement is called but an exception is still thrown by the end curly bracket below (the } below)
  // return;

}

And as I said, ConfigureAwait(false) allows my code to proceed normally, but an exception is always thrown by the end curly bracket of my method:

enter image description here

I am calling MyMethod(...) as follows (actually, PayPal Sandbox is calling my C# ASP.Net Webhook method and inside my Webhook method, the call is made to await MyMethod(...):

await MyMethod(json, headerDictionary);

The interesting thing is, if I remove all instances of Async and Await, and I forcefully call httpClient.PostAsync(...) synchronously, that is I call
httpClient.PostAsync(...).Result, everything works and I don’t get any exceptions at all:

var resultResponse = httpClient.PostAsync(payPalServHref + "/v1/notifications/verify-webhook-signature", content).Result;

Does anybody know why I keep getting exceptions when using Async and Await when calling httpClient.PostAsync(...) or calling httpClient.PostAsync(...).ConfigureAwait(false)?

Edit: Some people requested the function that is calling MyMethod(…). So here is the function that is calling MyMethod(…). It’s just a Webhook method that PayPal Sandbox calls:

public async Task<ActionResult> WebhookTester()
{
  try
  {
    // get the JSON from PayPal
    Stream req = Request.InputStream;
    req.Seek(0, System.IO.SeekOrigin.Begin);
    string json = new StreamReader(req).ReadToEnd();

    // Get the header from PayPal and store it in a dictionary
    var headers = HttpContext.Request.Headers;
    Dictionary<string, string> headerDictionary = new Dictionary<string, string>();
    var nvc = headers.AllKeys.SelectMany(headers.GetValues, (k, v) => new { key = k, value = v });
    foreach (var header in nvc)
    {
      headerDictionary.Add(header.key, header.value);
    }

    // Verify the JSON and header. If PayPal returns SUCCESS then process the order. If it's FAILURE, don't process the order.
    await MyMethod(json, headerDictionary);

  }
  catch (Exception ex)
  {

  }

  return new HttpStatusCodeResult(200);
}

2

Answers


  1. Chosen as BEST ANSWER

    I moved all my code from MyMethod(...) to WebhookTester(), including the await httpClient.PostAsync(...).ConfigureAwait(false) call. When I did that, no exception was thrown.

    I don't know the exact reason why calling await MyMethod(...) from my WebhookTester() method is causing the exception and why moving all the code to WebhookTester() works all of a sudden and no exceptions are thrown. My theory is that the class I am using that contains both WebhookTester() and MyMethod(...), is inheriting another base class, and some property in my base class is generating a null exception when await MyMethod(...) is finished being called. However, the Visual Studio debugger never shows me the null exception in my base class - my overall experience is that debugging asynchronous code with Visual Studio is pretty hard. Anyways, this is my theory - in the end, I don't know exactly why putting my code in await MyMethod(...) leads to an exception, but taking the same code and putting it in WebhookTester() does not cause an exception. Maybe it's also an issue with nested asynchronous methods where the class is inheriting another base class.


  2. I can’t comment yet, so apologies for writing an answer.

    This might be happening because you are using HttpClient as a static variable. Having said that, just reading Microsoft’s site, it suggests it is the correct way. If somewhere in the code HttpClient is being disposed, it could lead to an exception. Check if HttpClient is not disposed somewhere in the code.

    Try this with the using statement:

    private async Task MyMethod(string json, Dictionary<string, string> headerDictionary)
    {
        using (var httpClient = new HttpClient())
        {
            string accessToken = GetAccessToken();
            string webhookID = WebConfigurationManager.AppSettings["PayPalWebhookID"];
            var paypalVerifyRequestJsonString = ... ...;
            string payPalServHref = WebConfigurationManager.AppSettings["PayPalV2ServHref"];
    
            httpClient.DefaultRequestHeaders.Clear();
            httpClient.DefaultRequestHeaders.Add("authorization", "Bearer " + accessToken);
            var content = new StringContent(paypalVerifyRequestJsonString, Encoding.UTF8, "application/json");
    
            var resultResponse = await httpClient.PostAsync(payPalServHref + "/v1/notifications/verify-webhook-signature", content).ConfigureAwait(false);
    
            //...
        }
    }
    

    This helps prevent potential issues related to reusing the same HttpClient instance across multiple requests. Hope it helps

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search