HttpModule.cs
代码
namespace WebUploadFile{ public class HttpUploadModule : IHttpModule { /// <summary> /// IHttpModule Dispose /// </summary> public void Dispose(){} /// <summary> /// init begin request /// </summary> /// <param name="application"></param> public void Init(HttpApplication application) { application.BeginRequest += new EventHandler( this .Application_BeginRequest); } /// <summary> /// http request file is contains file upload /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Application_BeginRequest(Object sender, EventArgs e) { HttpApplication app = sender as HttpApplication; HttpWorkerRequest request = GetWorkerRequest(app.Context); Encoding encoding = app.Context.Request.ContentEncoding; int bytesRead = 0 ; // 已读数据大小 int read; // 当前读取的块的大小 int count = 8192 ; // 分块大小 byte [] buffer; // 保存所有上传的数据 if (request != null ) { // 返回 HTTP 请求正文已被读取的部分。 byte [] tempBuff = request.GetPreloadedEntityBody(); // 要上传的文件 // 如果是附件上传 if (tempBuff != null && IsUploadRequest(app.Request)) // 判断是不是附件上传 { // 获取上传大小 long length = long .Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength)); buffer = new byte [length]; count = tempBuff.Length; // 分块大小 // 将已上传数据复制过去 // Buffer.BlockCopy(tempBuff, // 源数据 0 , // 从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); } } } } 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 ); } } private static bool StringStartsWithAnotherIgnoreCase( string s1, string s2) { return ( string .Compare(s1, 0 , s2, 0 , s2.Length, true , CultureInfo.InvariantCulture) == 0 ); } /// <summary> /// 是否为附件上传 /// 判断的根据是ContentType中有无multipart/form-data /// </summary> /// <param name="request"></param> /// <returns></returns> bool IsUploadRequest(HttpRequest request) { return StringStartsWithAnotherIgnoreCase(request.ContentType, " multipart/form-data " ); } }}
Web.config 配置
代码
< httpModules > < add name = " ScriptModule " type = " System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35 " /> < add name = " HttpUploadModule " type = " WebUploadFile.HttpUploadModule, WebUploadFile " /> </ httpModules > < httpRuntime maxRequestLength = " 2000000 " executionTimeout = " 1300 " />
Page 代码
代码
< form id = " form1 " runat = " server " > < div > < input id = " firstFile " type = " file " name = " firstFile " runat = " server " /> < asp:Button ID = " Button1 " runat = " server " OnClick = " Button1_Click " Text = " 上传 " /> < asp:Label ID = " Label1 " runat = " server " ></ asp:Label > </ div > </ form >
Page.cs 代码
代码
protected void Button1_Click( object sender, EventArgs e) { // 要保存的位置 string strDesPath = " D:\\ " ; string strFileName = this .firstFile.PostedFile.FileName; strFileName = strDesPath + strFileName.Substring(strFileName.LastIndexOf( " \\ " )); // this .firstFile.PostedFile.SaveAs(strFileName); this .Label1.Text = " 文件保存到了: " + strFileName; }