首页 > 代码库 > 文件上传
文件上传
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";
}
}
}
3, web Config 中加入以下配置
<system.web>
<compilation targetFramework="4.0" debug="true"/>
<httpRuntime executionTimeout="6000" maxRequestLength="10000000000" />
<httpModules>
<add name="HttpUploadModule" type="myHttpModule.HttpUploadModule" />
</httpModules>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1000000000"/><!--100M 哦,还可以再大点哦 -->
</requestFiltering>
</security>
</system.webServer>
4,新建一个上传文件的页面,加入如下两个控件
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" onclick="btnUpload_Click"
Text="开始上传" />
click 的事件如下:(就最简单的保存一下,记得在和你的上传页面同一目录下创建一个文件夹叫file)
protected void btnUpload_Click(object sender, EventArgs e)
{
string fileName = System.IO.Path.GetFileName(this.FileUpload1.FileName);
string path = Server.MapPath("file/");
this.FileUpload1.SaveAs(path + fileName);
}
就这样, 按下F5 就可以运行上传文件了。就可以上传100M 以内的文件了。
如果你要部署到IIS7 上, 你需要 把程序部署在framework4 的application pool,用经典模式哦。
(怎么建立application pool,以及把你的应用程序部署到这个application pool 上,以及设置经典模式等,不会的会就问问你同事朋友哦,再不会也可以找我哦,这就不说了,太简单了。)
最后一步:如果你是透过ISS访问,一定要启用ISAPI AND CGI Restrictions 哦
文件上传