(转)利用HttpWebRequest上传文件应该注意的问题

 最近,在做一个Online Video的公司内部系统时,遇到一个利用HttpWebRequest上传文件时的问题,现象如下:
1、上传30M以下的文件速度很快,大概2-3m。
2、上传90-100M的文件速度在3-5m。
3、上传30M-90M这个区间的任意大小的文件都失败,用时100-101m,错误描述:The operation is time out。
4、将同样的文件用相同的程序,放在另外一台机器上work一切正常。
这个错误是framwork底层抛出来的,若根据这个错误描述查找问题是无法真正解决问题的。
首先,我将代码show出来,大家看看有没有问题:

 

  private static void UploadFile(Stream postedStream, string fileName,
             string uploadURL, string fileGroup, string fileType,
             string specialPath, string userName, string uploadType)
         {
             if (string.IsNullOrEmpty(uploadURL))
                 throw new Exception("Upload Web URL Is Empty.");
 
             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uploadURL);
 
            //Our method is post, otherwise the buffer (postvars) would be useless
            webRequest.Method = WebRequestMethods.Http.Post;

            // Proxy setting
            WebProxy proxy = new WebProxy();
            proxy.UseDefaultCredentials = true;
            webRequest.Proxy = proxy;

            //We use form contentType, for the postvars.
            webRequest.ContentType = "application/x-www-form-urlencoded";
   
            webRequest.Headers.Add("FileGroup", fileGroup);
            webRequest.Headers.Add("FileType", fileType);
            webRequest.Headers.Add("UploadType", uploadType);
            webRequest.Headers.Add("FileName", fileName);
            webRequest.Headers.Add("UserName", userName);
            webRequest.Headers.Add("SpecialFolderPath", specialPath);

            using (Stream requestStream = webRequest.GetRequestStream())
            {
                FileUtility.CopyStream(postedStream, requestStream);
            }
            try
            {
                webRequest.GetResponse().Close();
            }
            catch (WebException ex)
            {
                HttpWebResponse response = ex.Response as HttpWebResponse;
                if (response != null)
                {
                    throw new WebException(response.StatusDescription, ex);
                }

                throw ex;
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }

 

下面,我们来分析上述的现象,发现根本无法找到问题的根本,一头雾水。首先,可以肯定失败的原因是和文件的大小有关的,但是,发生错误的文件大小却是在一个区间段里的,这就无法解释了。然后,我们发现time out的时间都是刚刚超出100m,具体在100-101m之内;这个时间是在需要发送的Request里设的:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uploadURL);
....
webRequest.Timeout = 1000;//默认为100m,单位为毫秒
那我们就决定将这个时间设的更长一些,但是,根本没用。其实,我们能基本肯定问题不是在这里,因为在上传90M这么大的文件都能很轻易成功,根据这点我们就有理由怀疑问题不是在这里。但是,这种莫名的问题让我们无法理解,接着,我们就像没头苍蝇一样,将所有可以设置time out的地方都设了,比如IIS,接受上传的WebSite里的config里,结果,大家可想而知。
在代码层面我们已经找不到任何办法了,然后,我们只能怀疑是这台服务器的环境有问题,就把问题抛给了公司的IT。可怜了这些IT,怎么可能找到问题!
后来,美国的同事与微软的工作人员一起联调,终于发现了问题的所在,是我们在发送Request的时候没有精确的指定这个Request的ContentLength,导致Framework底层无法知道你什么时候需要终止这个Request,我们只要在上面的代码中增加这段话:
...
  webRequest.ContentType = "application/x-www-form-urlencoded";
  webRequest.ContentLength = postedStream.Length;
...
经过测试,发现果然是这个原因。但是,我们就有个问题,微软为什么不在底层处理好这些呢?我们认为微软在底层更能拿到我们的Request的长度,而且更容易包装,更利于使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值