mscorlib.dll throws 'System.NullReferenceException' when using SendAsync() function in ASP.NET 4.7.2

295 Views Asked by At

I have a web application (ASP.NET 4.7.2, C#). I am using HttpClient to do a POST request to webservice. When it comes to the point to execute this response = await client.SendAsync(request);

it throws An unhandled exception of type 'System.NullReferenceException' occurred in mscorlib.dll

I wrapped it around a try/catch but the exception doesn't get cought.

The exact same code works perfectly on WinForms App and on a Console project (!!).

Here is the exception that i get

   at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
   at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
   at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.AwaitTaskContinuation.<>c.<ThrowAsyncIfNecessary>b__18_0(Object s)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</StackTrace><ExceptionString>System.NullReferenceException: Δεν έχει οριστεί αναφορά αντικειμένου at μια παρουσία αντικειμένου.
   at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
   at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
   at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
   at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp;amp; currentTask)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.AwaitTaskContinuation.&amp;lt;&amp;gt;c.&amp;lt;ThrowAsyncIfNecessary&amp;gt;b__18_0(Object s)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</ExceptionString></Exception></TraceRecord>
An unhandled exception of type 'System.NullReferenceException' occurred in mscorlib.dll

And here is the stripped down code

public async Task<bool> SendPostRequestAsync()
{
    string endpoint = "endpointname";
    url = endpointUrl;
    var client = new HttpClient();
    var queryString = HttpUtility.ParseQueryString(string.Empty);

    // adding Request headers for authentication
    client.DefaultRequestHeaders.Add(...);
    client.DefaultRequestHeaders.Add(...);
    var uri = url + endpoint + "?" + queryString;

    HttpResponseMessage response = new HttpResponseMessage();

    byte[] byteData = Encoding.UTF8.GetBytes(bodyxml);
    using (var content = new ByteArrayContent(byteData))
    {
        try
        {
            Uri myUri = new Uri(uri, UriKind.Absolute);
            HttpRequestMessage request = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = myUri,
                Content = content
            };

            content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
            
            //this is to check if there nothing is null for the action
            bool iAmOk = ((client != null) && (response != null) && (url != null) && (request != null) && (bodyxml != null));
            if (!iAmOk) { return false; }
            
            try
            {
               response = await client.SendAsync(request);
               //here throws the exception
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                //it never goes here
            }
            var contents = response.Content.ReadAsStringAsync().Result;
            
            if (response.StatusCode == HttpStatusCode.OK)
            {
                // the call is successfull
                return true;
            }
            else
            {
                _log.Error("errordata");
                //the call is not successfull
                return false;
            }
        }
        catch (Exception exx)
        {
            //it doesn't go neither here
            _log.Error("exceptiondata");
            return false;
        }
   }
}

I am using

  • Microsoft Visual Studio Community 2019 Version 16.11.29
  • ASP.NET and Web Tools 2019 16.11.116.46506
  • ASP.NET Web Frameworks and Tools 2019 16.11.116.46506
  • .Net Framework 4.7.2

Is it a problem with the type of the application? Or with some libraries ?? (found this post that looks similar but does not have any answer yet. Any input would be appreciated!

4

There are 4 best solutions below

0
Magic Mick On

One potential issue in your code is that you are initializing the HttpResponseMessage variable response before making the asynchronous call, and then later trying to read from it. However, since the exception is thrown during the SendAsync call, it's possible that the response is still null at that point.

You can try to initialize response inside the try block, just before making the asynchronous call. This ensures that it's not null when you try to access it:

Eg.

//...

HttpResponseMessage response = null; // Initialize to null here

byte[] byteData = Encoding.UTF8.GetBytes(bodyxml);
using (var content = new ByteArrayContent(byteData))
{
     try
     {
        //...

        // Initialize response here
        response = await client.SendAsync(request);

        //...
    }
    catch (Exception ex)
    {
        string msg = ex.Message;
    }
    //...
}
2
karolgro On

Since the exception comes from System.Threading namespace I'd assume there is some issue with async/awaits. Also, each framework has different thread management (synchronization context to be more precise), it's not strange that code works properly in CLI and WinForms, while fails on ASP.NET

In your code, there is a code smell, which is very suspicious:

var contents = response.Content.ReadAsStringAsync().Result;

This is a synchronous wait in asynchronous method - a big no-no. Depending on internal implementation of this method and how Synchronization Context works in ASP.NET it might cause deadlocks or other failures. Please, in async methods use await call:

var contents = await response.Content.ReadAsStringAsync();

I hope this will fix the issue

1
Steffen Cole Blake On

I wrapped it around a try/catch but the exception doesn't get cought.

This almost always is caused by a missed await somewhere in the chain of calls above the point the exception is thrown. try { .. } catch { .. } wont work or breakpoint inside an async method, if anything in the calling chain above isn't doing a proper await.

I would start by working your way up the call stack and quadruple check you didn't accidently miss awaiting a Task somewhere. Quite often you will realize you passed a Task<T> instead of a T into a generic method.

Common example is when you do something like Deserialize(someObject), you can accidently pass in your Task<YourClass> into the that method instead of YourClass, because the method just takes in a generic object so it won't throw a compiler exception.

But when you run the code, you get your issue, the exceptions fail to catch and everything breaks, because your Task isn't getting awaited

2
athskar On

Thank you all for your suggestions. Each one helped me understand my problem better.

After days of working on this I figured it out.

In my .aspx file I had a button that triggered the whole process:

<asp:LinkButton runat="server" ID="button1" data-uk-tooltip="{pos:'left'}" title="start posting data" OnClick="button1_Click" class="md-fab md-fab-accent md-fab-wave"  >
             <i class="material-icons">cloud_upload</i>
 </asp:LinkButton>

The protected void button1_ClickAsync(object sender, EventArgs e) had in it this code

_ = myClass.RunSendAsync(var1,var2);

which was calling the public async Task<bool> SendPostRequestAsync() (from my question) BUT as I can understand this did not await the SendPostRequestAsync().

Tried these:

  1. Updated the project to .NET Framework 4.8 - didn't change much
  2. Cleaned temp files from .NET Temporary folder, cleaned solution and rebuilded - nothing changed
  3. Initialized the response inside the try block, before making the asynchronous call - still got the error
  4. Changed var contents = response.Content.ReadAsStringAsync().Result; to var contents = await response.Content.ReadAsStringAsync(); - still got the same error
  5. Changed the button1_ClickAsync to be async - I got a compiler error "The button1_ClickAsync has a wrong return type"

Finally, I changed the the LinkButton to anchor and then made the async call from jQuery AJAX

$("#button1").click(function () {
    
    $.ajax({
            type: 'POST',
            contentType: "application/json; charset=iso-8859-7",
            url: 'myurl/asyncmethod()',
            async: true,
            data: "{'var1':'value1'}",
            success: function (response) { //dothings
                },
            error: function (xhr) {
                    console.log(xhr.responseText);
                }
            });
});

And created a new WebMethod in my .cs file which calls AND awaits the myClass.RunSendAsync(var1,var2);

[WebMethod]
public static async void myAsyncMethod(string var1)
{
  //...
  await myClass.RunSendAsync(var1,var2);
  // ...
 }

and this worked like a charm!

UPDATE:

When i change the return type of the WebMethod from void to Task<List<Results>> and debug after the response = await client.SendAsync(request); it just stops and does not continue.

what can be wrong there?