REST API代码段在ASP.NET网页中抛出NullReferenceException,同时在WinForms中正常运行

时间:2018-02-19 17:27:46

标签: c# asp.net async-await nullreferenceexception

在WinForms中使用以下代码片段,我成功地通过REST API上传文档。但是一旦我转移到ASP.NET,它就会抛出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;
                }
            }
        }

我调试了clienturlByteArrayContent,但没有一个是null。但我仍然得到一个未处理的例外。

以下是例外情况的详细信息:

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

1 个答案:

答案 0 :(得分:0)

堆栈跟踪中存在“LegacyAspNetSynchronizationContext”是一个关于错误的线索。

如果要在ASP.NET 4.5中使用await,则必须在Web.config中添加以下元素:

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

documentation(强调添加):

  

设置此兼容性开关对于启用WebSockets的应用程序是必需的,用于在Web窗体页面中使用基于任务的异步,以及某些其他异步行为。

UPDATE:如果要从非异步方法调用异步方法,而不关心结果,那么一种方法是使用Task.Run:

Task.Run(() => TestUpload());