在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;
}
}
}
我调试了client
,url
和ByteArrayContent
,但没有一个是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()
答案 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());