简体   繁体   中英

REST API code snippet throws NullReferenceException in ASP.NET web page while running fine in WinForms

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()

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM