Asp.Net中怎么实现无刷新文件上传-创新互联

这篇文章给大家介绍Asp.Net中怎么实现无刷新文件上传,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

企业建站必须是能够以充分展现企业形象为主要目的,是企业文化与产品对外扩展宣传的重要窗口,一个合格的网站不仅仅能为公司带来巨大的互联网上的收集和信息发布平台,创新互联建站面向各种领域:效果图设计成都网站设计成都营销网站建设解决方案、网站设计等建站排名服务。

一、创建Html网页
1、在创建的Web工程中添加一个Html文件,命名为UploadFile.htm,在头文件中引入JQuery,JQuery UI


复制代码 代码如下:



  
  



2、关于无刷新文件上传

通过Ajax是不能上传文件的,无刷新上传是靠隐藏的iframe来实现的


复制代码 代码如下:











要将form标签的target属性设置为iframe的id,当然别忘了将form的enctype设置为multipart/form-data


复制代码 代码如下:




是用来显示上传文件时的进度条

在JS中加入如下处理:


复制代码 代码如下:


  



此时效果:

Asp.Net中怎么实现无刷新文件上传

二、实现文件上传
添加一个一般处理程序,命名为UploadFileHandler.ashx


复制代码 代码如下:


       public void ProcessRequest(HttpContext context)
       {
           //如果提交的文件名是空,则不处理
           if (context.Request.Files.Count == 0 || string.IsNullOrWhiteSpace(context.Request.Files[0].FileName))
               return;
           //获取文件流
           Stream stream = context.Request.Files[0].InputStream;
           //获取文件名称
           string fileName = Path.GetFileName(context.Request.Files[0].FileName);
           //声明字节数组
           byte[] buffer;
           //为什么是4096呢?这是操作系统中最小的分配空间,如果你的文件只有100个字节,其实它占用的空间是4096个字节
           int bufferSize = 4096;
           //获取上传文件流的总长度
           long totalLength = stream.Length;
           //已经写入的字节数,用于做上传的百分比
           long writtenSize = 0;
           //创建文件
           using (FileStream fs = new FileStream(@"C:\" + fileName, FileMode.Create, FileAccess.Write))
           {
               //如果写入文件的字节数小于上传的总字节数,就一直写,直到写完为止
               while (writtenSize < totalLength)
               {
                   //如果剩余的字节数不小于最小分配空间
                   if (totalLength - writtenSize >= bufferSize)
                   {
                       //用最小分配空间创建新的字节数组
                       buffer = new byte[bufferSize];
                   }
                   else
                       //用剩余的字节数创建字节数组
                       buffer = new byte[totalLength - writtenSize];
                   //读取上传的文件到字节数组
                   stream.Read(buffer, 0, buffer.Length);
                   //将读取的字节数组写入到新建的文件流中
                   fs.Write(buffer, 0, buffer.Length);
                   //增加写入的字节数
                   writtenSize += buffer.Length;
                   //计算当前上传文件的百分比
                   long percent = writtenSize * 100 / totalLength;
               }
           }
       }



在form中添加action和method属性,修改之后的


复制代码 代码如下:




这样文件上传就完成了。

三、实现文件上传的进度显示
我的思路:

文件上传的处理过程中,是不可以在处理过程中将信息传回客户端的,只有当所有的处理都完毕之后才会传回客户端,所以如果是在上面的处理程序中写 入context.Response.Write(percent);是不可能得到处理的过程,只能等到处理结束后,客户端一次性得到所有的值。

要想得到处理过程中的值,我的解决是这样,在文件上传时,要开启另一个请求,来获取进度信息。而这个请求是异步的,我指的是客户端异步请求和服 务端异步处理。因为要涉及到两个不同的请求处理程序之间信息的传递,将"处理文件上传的程序"得到的进度信息传递给"处理进度请求的程序",而"处理进度 请求的处理程序"要依赖于"处理文件上传的处理程序"。处理图:

Asp.Net中怎么实现无刷新文件上传

首先客户端同时(几乎是)发出两个请求,一个是文件上传,一个是进度请求。由于"处理请求进度的程序"是异步处理的,当该程序没有信息发给客户 端时,我们让它处于等待状态,这里有点像Tcp,这样客户端跟服务器就一直处于连接状态。当"处理文件上传的程序"开始处理时,通过把进度值赋值给"处理 请求进度程序"的异步操作的状态,并触发"处理请求进度的程序"返回值给客户端。客户端获取进度值,并处理。这样一次请求进度值的请求就结束了,我们知道 服务器是不会主动给客户端发送信息的,只有客户端请求,服务器才会响应。显然,要想在文件保存的过程中向客户端发送进度信息,客户端得到每得到一个返回结 果,都是一次请求。为了得到连续的请求值,客户端再向"处理请求进度的程序"发出请求,依次循环,知道文件上传结束。

技术实现:
异步处理用到接口IHttpAsyncHandler,新建一个一般处理程序,命名为RequestProgressAsyncHandler.ashx,将默认的接口改为IHttpAsyncHandler


复制代码 代码如下:


   public class RequestProgressAsyncHandler : IHttpAsyncHandler
   {
       public void ProcessRequest(HttpContext context)
       {
       }
       public bool IsReusable
       {
           get
           {
               return false;
           }
       }
       #region IHttpAsyncHandler 成员
       public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
       {
           throw new NotImplementedException();
       }
       public void EndProcessRequest(IAsyncResult result)
       {
           throw new NotImplementedException();
       }
       #endregion
   }



BeginProcessRequest和EndProcessRequest是两个核心的方法,其他的两个不用处理。当该处理程序处理请求 时,BeginProcessRequest是第一个被调用的函数,返回一个包含异步状态信息的对象,该对象是IAsyncResult类型,是实现异步 的关键,用于控制什么时候调用EndProcessRequest来结束处理程序的等待状态,BeginProcessRequest被调用之后,程序就 处于等待状态。EndProcessRequest是在结束请求时的处理函数,通过该函数可以向客户端写入信息。

实现接口IAsyncResult

复制代码 代码如下:


   public class AsyncResult : IAsyncResult
   {
       // 标示异步处理的状态
       private bool isComplete = false;

        //保存异步处理程序中的Http上下文
       private HttpContext context;

        //异步回调的委托
       private AsyncCallback callback;
       ///


       /// 获取或设置保存下载文件的百分比数值部分
       ///

       public long PercentNumber;

        public AsyncResult(HttpContext context, AsyncCallback callback)
       {
           this.context = context;
           this.callback = callback;
       }
       ///


       /// 向客户端写入信息
       ///

       public void Send()
       {
           this.context.Response.Write(PercentNumber);
       }
       ///
       /// 完成异步处理,结束请求
       ///

       public void DoCompleteTask()
       {
           if (callback != null)
               callback(this);//会触发处理程序中的EndProcessRequest函数,结束请求
           this.isComplete = true;
       }
       #region IAsyncResult 成员

        public object AsyncState
       {
           get { return null; }
       }

        public System.Threading.WaitHandle AsyncWaitHandle
       {
           get { return null; }
       }

        public bool CompletedSynchronously
       {
           get { return false; }
       }

        public bool IsCompleted
       {
           get { return isComplete; }
       }

        #endregion

    }

修改 RequestProgressAsyncHandler.ashx文件:


复制代码 代码如下:


   public class RequestProgressAsyncHandler : IHttpAsyncHandler
   {
       ///


       /// 保存异步处理状态信息的集合
       ///

       public static List AsyncResults = new List();
       public void ProcessRequest(HttpContext context)
       {
       }
       public bool IsReusable
       {
           get
           {
               return false;
           }
       }
       #region IHttpAsyncHandler 成员

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
       {

            AsyncResult result = new AsyncResult(context, cb);
           AsyncResults.Add(result);
           return result;
       }

        public void EndProcessRequest(IAsyncResult result)
       {
           //保证集合中只用一个元素
           AsyncResults.Clear();
           AsyncResult ar = (AsyncResult)result;
           ar.Send();
       }

        #endregion
   }

在UploadFileHandler.ashx添加如下代码:


复制代码 代码如下:


       private static void SendPercentToClient(long percent)
       {
           //当上传完毕后,保证处理程序能向客户端传回
           while (RequestProgressAsyncHandler.AsyncResults.Count == 0 && percent == 100)
           {

            }
           //因为本处理程序和"处理请求进度的程序"是并发的,不能保证RequestProgressAsyncHandler.AsyncResults一定含有子项
           if (RequestProgressAsyncHandler.AsyncResults.Count != 0)
           {
               RequestProgressAsyncHandler.AsyncResults[0].PercentNumber = percent;
               RequestProgressAsyncHandler.AsyncResults[0].DoCompleteTask();
           }
       }

在函数ProcessRequest中加入以上方法:


复制代码 代码如下:


         ...
                    ...
         //计算当前上传文件的百分比
                   long percent = writtenSize * 100 / totalLength;

                    SendPercentToClient(percent);

服务端OK!修改客户端,添加JS处理函数:


复制代码 代码如下:


       function RequestProgress() {
           $.post("RequestProgressAsyncHandler.ashx", function (data, status) {
               if (status == "success") {
                   $("#progressValue").text(data + "%");
                   data = parseInt(data);
                   $("#progressBar").progressbar({ value: data });//JQuery UI 设置进度条值
                   //如果进度不是 100,则重新请求
                   if (data != 100) {
                       RequestProgress();
                   }
               }
           });
       }



在form中添加事件omsubmit的处理函数为RequestProgress


复制代码 代码如下:




补充几点:
1.默认Asp.Net允许的上传文件的大小是4M,可以在Web.config中修改其大小限制


复制代码 代码如下:


  
      
  



maxRequestLength的单位是KB

2.在IE 8.0测试中,在文件上传完毕后,状态栏还处于请求中

Asp.Net中怎么实现无刷新文件上传

关于Asp.Net中怎么实现无刷新文件上传就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


本文名称:Asp.Net中怎么实现无刷新文件上传-创新互联
当前地址:http://www.csdahua.cn/article/ejdhp.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流