首页 > 代码库 > 文件上传

文件上传

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 哦

 

技术分享

文件上传