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 " );
}
}
}
{
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 " />
< 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 >
< 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;
}
{
// 要保存的位置
string strDesPath = " D:\\ " ;
string strFileName = this .firstFile.PostedFile.FileName;
strFileName = strDesPath + strFileName.Substring(strFileName.LastIndexOf( " \\ " ));
//
this .firstFile.PostedFile.SaveAs(strFileName);
this .Label1.Text = " 文件保存到了: " + strFileName;
}