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>
上傳大於1G的文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.