鸿钧之师,大宋王朝赵匡胤电视剧,乱世激流txt
相信通过asp.net的服务器控件上传文件在简单不过了,通过ajaxtoolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦苦来 实现呢?我并不否认”拿来主义“,只是我个人更喜欢凡是求个所以然。本篇将阐述通过html,ihttphandler和 ihttpasynchandler实现文件上传和上传进度的原理,希望对你有多帮助。
效果图:
本文涉及到的知识点:
1.前台用到html,ajax,jquery,jquery ui
2.后台用到一般处理程序(ihttphandler)和一般异步处理程序(ihttpasynchandler),并涉及到”推模式“
一、创建html网页
1、在创建的web工程中添加一个html文件,命名为uploadfile.htm,在头文件中引入jquery,jquery ui
通过ajax是不能上传文件的,无刷新上传是靠隐藏的iframe来实现的
在js中加入如下处理:
二、实现文件上传
添加一个一般处理程序,命名为uploadfilehandler.ashx
三、实现文件上传的进度显示
我的思路:
文件上传的处理过程中,是不可以在处理过程中将信息传回客户端的,只有当所有的处理都完毕之后才会传回客户端,所以如果是在上面的处理程序中写 入context.response.write(percent);是不可能得到处理的过程,只能等到处理结束后,客户端一次性得到所有的值。
要想得到处理过程中的值,我的解决是这样,在文件上传时,要开启另一个请求,来获取进度信息。而这个请求是异步的,我指的是客户端异步请求和服 务端异步处理。因为要涉及到两个不同的请求处理程序之间信息的传递,将"处理文件上传的程序"得到的进度信息传递给"处理进度请求的程序",而"处理进度 请求的处理程序"要依赖于"处理文件上传的处理程序"。处理图:
首先客户端同时(几乎是)发出两个请求,一个是文件上传,一个是进度请求。由于"处理请求进度的程序"是异步处理的,当该程序没有信息发给客户 端时,我们让它处于等待状态,这里有点像tcp,这样客户端跟服务器就一直处于连接状态。当"处理文件上传的程序"开始处理时,通过把进度值赋值给"处理 请求进度程序"的异步操作的状态,并触发"处理请求进度的程序"返回值给客户端。客户端获取进度值,并处理。这样一次请求进度值的请求就结束了,我们知道 服务器是不会主动给客户端发送信息的,只有客户端请求,服务器才会响应。显然,要想在文件保存的过程中向客户端发送进度信息,客户端得到每得到一个返回结 果,都是一次请求。为了得到连续的请求值,客户端再向"处理请求进度的程序"发出请求,依次循环,知道文件上传结束。
技术实现:
异步处理用到接口ihttpasynchandler,新建一个一般处理程序,命名为requestprogressasynchandler.ashx,将默认的接口改为ihttpasynchandler
实现接口iasyncresult
//保存异步处理程序中的http上下文
private httpcontext context;
//异步回调的委托
private asynccallback callback;
/// <summary>
/// 获取或设置保存下载文件的百分比数值部分
/// </summary>
public long percentnumber;
public asyncresult(httpcontext context, asynccallback callback)
{
this.context = context;
this.callback = callback;
}
/// <summary>
/// 向客户端写入信息
/// </summary>
public void send()
{
this.context.response.write(percentnumber);
}
/// <summary>
/// 完成异步处理,结束请求
/// </summary>
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
}
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
}
}
//因为本处理程序和"处理请求进度的程序"是并发的,不能保证requestprogressasynchandler.asyncresults一定含有子项
if (requestprogressasynchandler.asyncresults.count != 0)
{
requestprogressasynchandler.asyncresults[0].percentnumber = percent;
requestprogressasynchandler.asyncresults[0].docompletetask();
}
}
sendpercenttoclient(percent);
2.在ie 8.0测试中,在文件上传完毕后,状态栏还处于请求中
反正不是后台还在请求,这个放心,只要把鼠标在按钮和浏览上面来回移动几下就没了,可能是jquery ui 的问题。ff和chrom下没这个问题,就是显示效果会有点差,但是上传没问题的。
源代码下载:uploadfiledemo.rar
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Blazor server side 自家的一些开源的, 实用型项目的进度之 CEF客户端
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布
网友评论