2016-08-16 25 views
1

我試圖爲API實現HMAC安全性。一切工作正常,直到我試圖發佈數據值旁邊的MultipartFormDataContent文件。當多個內容類型存在時,閱讀HttpContent字節在DelegatingHandler內部失敗

HttpClientDelegatingHandler當讀取字節的異步代碼行被命中時,會自動失敗。

下面的代碼建立請求:

private FileOutputViewModel GetApiOutput(Uri apiResource, string filename, byte[] file, IDictionary<string, string> extraParameters) 
{ 
    FileOutputViewModel result = new FileOutputViewModel(); 

    if (file != null) 
    { 
     using (var content = new MultipartFormDataContent()) 
     { 
      if (extraParameters != null) 
      { 
       foreach (var param in extraParameters) 
       { 
        content.Add(new StringContent(param.Value), param.Key); // <- If I don't have this, everything works fine 
       } 
      } 

      var fileContent = new ByteArrayContent(file); 
      fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
      { 
       FileName = filename 
      }; 
      content.Add(fileContent); 

      var response = HttpClient.PostAsync(apiResource.ToString(), content).Result; 

      result.Output = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result); 

      result.Filename = Path.GetFileName(filename); 
     } 
    } 

    return result; 
} 

如果我不使用DelegatingHandler一切工作正常,但HMAC安全沒有爲請求,從而被拒絕對API的結束來實現。

如果我不在文件旁邊使用StringContent項目添加數據值,那麼讀取字節沒有問題。但我留下了一個不完整的請求,因爲我需要將更多信息與文件一起傳遞。

的代碼,在DelegatingHandler失敗,該生產線如下所示:

private static async Task<byte[]> ComputeHash(HttpContent httpContent) 
{ 
    using (var md5 = MD5.Create()) 
    { 
     byte[] hash = null; 
     if (httpContent != null) 
     { 
      var ms = new MemoryStream(); 
      await httpContent.CopyToAsync(ms); // <- Fails here 
      ms.Seek(0, SeekOrigin.Begin); 

      var content = ms.ToArray(); 
      if (content.Length != 0) 
      { 
       hash = md5.ComputeHash(content); 
      } 
     } 
     return hash; 
    } 
} 

最初的失敗行是:

var content = await httpContent.ReadAsByteArrayAsync(); 

但這種失敗,甚至只是對自己的文件(前Stackoverflow question)。使用MemoryStream是向前邁出的一步,但一直沒有讓我走。

任何想法我可能能夠解決這個問題?

回答

1

似乎這是由於有System.Net.Http.DelegatingHandler.SendAsync方法的異步簽名造成的。最初委託倍率爲:

protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 

當我適應的代碼,所以我可以將其更改爲:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 

一切開始按預期運行。

似乎.NET框架的這一部分必須存在線程問題。如果您需要嘗試其他解決方法,還有其他一些解決方法:https://social.msdn.microsoft.com/Forums/vstudio/en-US/55f5571d-fe94-4b68-b1d4-bfb91fd721dd/reading-httpcontent-bytes-fails-inside-delegatinghandler-when-multiple-content-types-present?forum=wcf