发送大文件/内容时HttpClient存在缺陷吗?

时间:2014-12-22 01:05:52

标签: c# .net-4.5

在阅读/浏览HttpClient之后,我觉得这个组件不适合将大文件或内容上传到REST服务。

  1. 似乎如果上传超过建立的超时,传输将失败。是否有意义?这个超时是什么意思?

  2. 获取进度信息似乎很难或需要附加组件。

  3. 所以我的问题是:是否有可能在没有太多麻烦的情况下解决这两个问题?否则,在处理大型内容和REST服务时,最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

  1. 是的,如果上传时间超过TimeOut,则上传将失败。这是HttpClient的限制。这个问题的最有效解决方案是Thomas Levesque written an article about {{}} {{}} {}} {}} {{}}您必须使用HttpWebRequest代替HttpClient
  2. 如果要获取进度消息,请将文件作为FileStream打开并手动迭代,将增量字节复制到(上传)请求流中。随着时间的推移,您可以计算相对于文件大小的进度。
  3. TL的代码示例。 Be sure to read the article though!

    long UploadFile(string path, string url, string contentType)
    {
        // Build request
        var request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = WebRequestMethods.Http.Post;
        request.AllowWriteStreamBuffering = false;
        request.ContentType = contentType;
        string fileName = Path.GetFileName(path);
        request.Headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", fileName);
    
        try
        {
            // Open source file
            using (var fileStream = File.OpenRead(path))
            {
                // Set content length based on source file length
                request.ContentLength = fileStream.Length;
    
                // Get the request stream with the default timeout
                using (var requestStream = request.GetRequestStreamWithTimeout())
                {
                    // Upload the file with no timeout
                    fileStream.CopyTo(requestStream);
                }
            }
    
            // Get response with the default timeout, and parse the response body
            using (var response = request.GetResponseWithTimeout())
            using (var responseStream = response.GetResponseStream())
            using (var reader = new StreamReader(responseStream))
            {
                string json = reader.ReadToEnd();
                var j = JObject.Parse(json);
                return j.Value<long>("Id");
            }
        }
        catch (WebException ex)
        {
            if (ex.Status == WebExceptionStatus.Timeout)
            {
                LogError(ex, "Timeout while uploading '{0}'", fileName);
            }
            else
            {
                LogError(ex, "Error while uploading '{0}'", fileName);
            }
            throw;
        }
    }