I'm trying to implement HMAC security for an API. Everything works fine until I try to post data values alongside a file in a MultipartFormDataContent.
The HttpClient DelegatingHandler fails silently when the async line of code to read bytes is hit.
Here's the code building the request:
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;
}
If I don't use the DelegatingHandler everything works fine, but the HMAC security isn't implemented for the request so is rejected on the API's end.
If I don't add the data values using StringContent items alongside the file then there's no problem reading the bytes. But I'm left with an incomplete request as I need to pass more info along with the file.
The line of code that fails in the DelegatingHandler is indicated below:
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;
    }
}
Originally the failing line was:
var content = await httpContent.ReadAsByteArrayAsync();
but this failed with even just the file on its own (previous Stackoverflow question). Using a MemoryStream was one step forward but hasn't got me all the way.
Any ideas how I might be able to work around this issue?