3

Using the following code snippet in WinForms, I am successfully able to upload documents through a REST API. But as soon as I move to ASP.NET, it throws a NullReferenceException.

public async Task<string> TestUpload()
    {
        const string cServerBaseAddress = "https://test-testrestservice.abcd.com/";
        const string cFilename = @"D:\temp\Test.txt";
        const string cUrl = "{0}abc/dms/api/v1/crmdocuments/?BusinessUnit={1}&AccountID={2}&DocumentType={3}&Description={4}&Filename={5}";
        string businessUnit = "XYZ";
        string accountID = "ABCCompany";
        string docType = "Affidavit";
        string description = @"\%&description&%/";
        string responseContent = string.Empty;
        try
        {
            string url = string.Format(cUrl, cServerBaseAddress,
            WebUtility.UrlEncode(businessUnit), WebUtility.UrlEncode(accountID),
            WebUtility.UrlEncode(docType), WebUtility.UrlEncode(description),
            WebUtility.UrlEncode(Path.GetFileName(cFilename)));
            using (HttpClient client = GetClient(cServerBaseAddress))
            {
                using (HttpResponseMessage response = await client.PostAsync(url, new ByteArrayContent(File.ReadAllBytes(cFilename))))
                {
                    responseContent = await response.Content.ReadAsStringAsync();
                    response.EnsureSuccessStatusCode();
                    string newContentId = Newtonsoft.Json.Linq.JToken.Parse(response.Content.ReadAsStringAsync().Result).ToString();
                    return newContentId;
                }
            }
        }

I've debugged the client, url, and ByteArrayContent, and none of them is null. But I am still getting an unhandled exception.

Here are the details of the exception:

   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& currentTask)
--- End of stack trace from previous location where exception was thrown ---
   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()
5
  • Null exception on what specifically? It could be that you are missing the url and or a config setting. Commented Feb 19, 2018 at 17:42
  • I checked I've none of them is null or empty. I've also updated the question with stack trace Commented Feb 19, 2018 at 17:43
  • A few points that might not fix the specific issue: a) call EnsureSuccessStatusCode() before you try to read the content; b) you don't declare responseContent in this code, so where is it declared?; c) it could be this is just an adjusted code snippet, but in general do not create and dispose HttpClient like that for each request - create one instance and use it for your whole app, as intended; d) change response.Content.ReadAsStringAsync().Result to just responseContent. Commented Feb 19, 2018 at 18:12
  • @sellotape this is the part of whole program to upload document through api. its almost more than 1500 lines of code, if you wish I would update here as well Commented Feb 19, 2018 at 18:17
  • @J.Doe - I don't think anyone wants (or will read) 1500 lines of code in a SO question :) Have you tried Michael Liu's answer, as well as running EnsureSuccessStatusCode() first? Could be you're getting a non 2xx response. Commented Feb 19, 2018 at 18:22

1 Answer 1

1

The presence of "LegacyAspNetSynchronizationContext" in your stack trace is a clue as to what's wrong.

If you want to use await in ASP.NET 4.5, then you must add the following element in Web.config:

<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>

From the documentation (emphasis added):

Setting this compatibility switch is mandatory for WebSockets-enabled applications, for using Task-based asynchrony in Web Forms pages, and for certain other asynchronous behaviors.

UPDATE: If you want to call an async method from a non-async method, and you don't care about the result, then one way to do so is to use Task.Run:

Task.Run(() => TestUpload());
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks Mich, I added that snippet to <configuration>. Now, I am not facing the exception but the breakpoint is not hitting back to the last block of code.
Edit your post and show how you're calling this code snippet. You might be encountering a deadlock (which could happen if you're accessing the Result property of a Task).
This function is put in one function, and the whole function is called all at once. I've updated the code as well
it is called upon a button click, TestUpload();
Are you awaiting the result, or accessing the Task's Result property?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.