PostAsync方法的HttpClient错误

时间:2014-04-10 15:59:17

标签: c# asp.net-mvc webclient

使用HttpClient对第三方API进行PostAsync调用时。当我做client.PostAsync时,我正好看到这个错误。知道是什么导致了这个吗?

代码:

public class JobController : AsyncController
{
    public ActionResult ViewPage()
    {
        return View("~/Views/Pages/Submit.cshtml");
    }

    private const string ServiceUrl = "https://api.3points.io/v1/applications/";

    [HttpPost]
    public async Task<ActionResult> Submit()
    {
        var client = new HttpClient();
        var formData = new MultipartFormDataContent();
        var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("abc123"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encoded);

        foreach (var key in Request.Form.AllKeys)
            formData.Add(new StringContent(Request.Form[key]), String.Format("\"{0}\"", key));

        foreach (string key in Request.Files.AllKeys)
        {
            var file = Request.Files[key];
            if (file == null || file.ContentLength <= 0) continue;

            HttpContent fileStream = new StreamContent(file.InputStream);
            formData.Add(fileStream, key, file.FileName);
        }

        var response = await client.PostAsync(ServiceUrl, formData);

        var success = "True";
        if (!response.IsSuccessStatusCode) success = "False";

        return new JsonResult { Data = success };
    }
}

错误:

System.NullReferenceException was unhandled 
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=System.Web
StackTrace:
   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.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.<ThrowAsyncIfNecessary>b__1(Object s)
   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()

2 个答案:

答案 0 :(得分:5)

将这两行添加到您的web.config文件中:

// First tag might exist already
<httpRuntime targetFramework="4.5" />
<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

我引用this link

  

启用新的等待友好的异步管道   在4.5中介绍。我们之前的许多同步原语   ASP.NET的版本具有不良行为,例如在公共上获取锁定   对象或违反API合同。事实上,ASP.NET 4   SynchronizationContext.Post的实现是一个阻塞   同步通话!新的异步管道力求做得更多   高效,同时也遵循其API的预期合同。   新管道还执行少量错误检查   代表开发人员,例如检测意外的呼叫   async void方法。

     

WebSockets等某些功能需要设置此开关。   重要的是,ASP.NET中未定义async / await的行为   除非已设置此开关。 (请记住:设置也足够了。)

答案 1 :(得分:3)

我会改变

var response = client.PostAsync(ServiceUrl, formData).Result

var response = await client.PostAsync(ServiceUrl, formData);

然后监视错误。