现在的位置: 首页 > 综合 > 正文

上传超大文件的httpModule

2012年08月01日 ⁄ 综合 ⁄ 共 3984字 ⁄ 字号 评论关闭

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web;
using System.Reflection;

namespace myHttpModule
{
 /// <summary>
 /// HttpUploadModule 的摘要说明。
 /// </summary>
 public class HttpUploadModule: IHttpModule
 {
  public HttpUploadModule()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
  public void Init(HttpApplication application)
  {
   application.BeginRequest += new EventHandler(this.Application_BeginRequest);
   application.EndRequest += new EventHandler(this.Application_EndRequest);
   application.Error += new EventHandler(this.Application_Error);
  }

  public void Dispose()
  {
  }

  private void Application_BeginRequest(Object sender, EventArgs e)
  {
   HttpApplication app = sender as HttpApplication;

   // 如果是文件上传
   if (IsUploadRequest(app.Request))
   {
    // 返回 HTTP 请求正文已被读取的部分。
    HttpWorkerRequest request = GetWorkerRequest(app.Context);
    Encoding encoding = app.Context.Request.ContentEncoding;

    int bytesRead = 0; // 已读数据大小
    int read; // 当前读取的块的大小
    int count = 8192; // 分块大小
    byte[] buffer; // 保存所有上传的数据
    byte[] tempBuff = null;
    
    if (request != null)
    {
     tempBuff = request.GetPreloadedEntityBody();
    }
    if (tempBuff != null)
    {
     // 获取上传大小
     //
     long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
    
     buffer = new byte[length];
     count = tempBuff.Length; // 分块大小

     // 将已上传数据复制过去
     //
     Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, count);

     // 开始记录已上传大小
     //
     bytesRead = tempBuff.Length;

     // 循环分块读取,直到所有数据读取结束
     //
     while (request.IsClientConnected() &&
      !request.IsEntireEntityBodyIsPreloaded() &&
      bytesRead < length
      )
     {
      // 如果最后一块大小小于分块大小,则重新分块
      //
      if (bytesRead + count > length)
      {
       count = (int)(length - bytesRead);
       tempBuff = new byte[count];
      }

      // 分块读取
      //
      read = request.ReadEntityBody(tempBuff, count);
     
      // 复制已读数据块
      //
      Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);
     
      // 记录已上传大小
      //
      bytesRead += read;

     }
     if (
      request.IsClientConnected() &&
      !request.IsEntireEntityBodyIsPreloaded()
      )
     {
   
      // 传入已上传完的数据
      //
      InjectTextParts(request, buffer);

      // 表示上传已结束

     }
    }
   }
  }

  /// <summary>
  /// 结束请求后移除进度信息
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void Application_EndRequest(Object sender, EventArgs e)
  {

  }

  /// <summary>
  /// 如果出错了设置进度信息中状态为“Error”
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void Application_Error(Object sender, EventArgs e)
  {

  }

  HttpWorkerRequest GetWorkerRequest(HttpContext context)
  {

   IServiceProvider provider = (IServiceProvider)HttpContext.Current;
   return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
  }

  /// <summary>
  /// 传入已上传完的数据
  /// </summary>
  /// <param name="request"></param>
  /// <param name="textParts"></param>
  void InjectTextParts(HttpWorkerRequest request, byte[] textParts)
  {
   BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
  
   Type type = request.GetType();
  
   while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
   {
    type = type.BaseType;
   }

   if (type != null)
   {
    type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);

    type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
    type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);

    type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
   }
  }

  /// <summary>
  /// 是否为附件上传
  /// 判断的根据是ContentType中有无multipart/form-data
  /// </summary>
  /// <param name="request"></param>
  /// <returns></returns>
  bool IsUploadRequest(HttpRequest request)
  {
   return request.ContentType.ToLower()=="multipart/form-data";
  }

 }
}

需要在web.config中加入

   <httpRuntime executionTimeout="600" maxRequestLength="1048576"/>

 <httpModules>

  <add name="HttpUploadModule" type="myHttpModule" />
 </httpModules>

欢迎访问:http://121.18.78.216 适易查询分析、工作流、内容管理及项目管理演示平台

 

抱歉!评论已关闭.