最近在做ASP.NET 2.0的应用时候发现Session并不能很好的保存HtmlInputFile这个控件,具体表现是:如果客户机和服务机是一台的话(一般单机开发情况都是这样)Session能很好的保存任何对象,但是如果把项目发布部署到真正的服务器上Session只能保存很小的一笔数据,对于稍微大点的文件就提示“无法访问已关闭的文件”,意思应该是我的InputStream流早就关闭了,根本没法再读取了。查了一下ASP.NET 2.0的Web.config的配置也都没能解决这个现象,索性不用Session来存储了,改成Cache(ViewState也能存储只是需要更新到页面,效率很低,所以没有采用)。前面说道了HtmlInputFile控件中包含了流对象,这样控件无法被序列化也就没有办法直接保存到一个Cache对象中,所以我只好又写了一个表示文件的类(CustomFile)来保存上传文件的相关信息。
类定义,FileBytes是二进制文件的数据类型byte[],FileContentType文件MIME类型,FileSize文件的大小,FullFileName表示带路径的文件全名,最后还有一个SaveAs方法用来保存到服务器指定路径中。
接下来的事情就是要把CustomFile这个类的实例都保存到Cache中,以便以后一次全部上传到服务器。这样的工作笔者通过一个用户控件来实现,方便快捷。用户通过“浏览”选择本地文件,用“增加”把文件加载到指定Cache中,“删除”可以删除掉选择错的文件。控件的截图
控件就一个最重要的对外属性GetFiles,通过这个方法可以获取保存在Cache中的CustomFile数组(即表示多个上传文件)。
还有一个方法Clear是上传后来清空Cache的,非常重要一定要使用,否则还会继续上传上次已经传过的文件!!!
控件说明
文件上传控件ID:FileUpload1
增加按钮ID:btnAdd
删除按钮ID:btnDelete
文件列表ID:LbFiles
源代码:
public partial class FileUploadControl : System.Web.UI.UserControl
{
/// <summary>
/// 预先定义一个Cache名称
/// </summary>
private string _vName = "MyFile";
private ArrayList _FileInfo = new ArrayList();
private CustomFile Files
{
set
{
if ( Cache["" + _vName + ""] != null )
{
_FileInfo = (ArrayList) Cache["" + _vName + ""];
}
else
_FileInfo = new ArrayList();
_FileInfo.Add( value );
Cache["" + _vName + ""] = _FileInfo;
}
}
/// <summary>
/// 获取自定义上传文件类
/// </summary>
public CustomFile[ ] GetFiles
{
get
{
if ( Cache["" + _vName + ""] != null )
{
_FileInfo = (ArrayList) Cache["" + _vName + ""];
}
else
_FileInfo = new ArrayList();
return (CustomFile[ ]) _FileInfo.ToArray( typeof( CustomFile ) );
}
}
/// <summary>
/// 清除已经上载过的文件
/// </summary>
public void Clear ()
{
Cache.Remove( "" + _vName + "" );
LbFiles.Items.Clear();
}
/// <summary>
/// 删除附件
/// </summary>
/// <param name="p_FileName">文件全名</param>
private void DeleteFile ( string p_FileName )
{
if ( Cache["" + _vName + ""] != null )
{
for ( int i = 0; i < GetFiles.Length; i++ )
{
if ( GetFiles[i].FullFileName == LbFiles.SelectedItem.Text )
{
( (ArrayList) Cache["" + _vName + ""] ).RemoveAt( i );
}
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click ( object sender, EventArgs e )
{
CustomFile _cf = new CustomFile();
_cf.FileBytes = FileUpload1.FileBytes;
_cf.FullFileName = FileUpload1.PostedFile.FileName;
_cf.FileSize = FileUpload1.PostedFile.ContentLength;
_cf.FileContentType = FileUpload1.PostedFile.ContentType;
Files = _cf;
LbFiles.Items.Add( _cf.FullFileName );
}
protected void btnDelete_Click ( object sender, EventArgs e )
{
int ItemCount = LbFiles.Items.Count;
for ( int j = 0; j < ItemCount; j++ )
{
for ( int i = 0; i < LbFiles.Items.Count; i++ )
{
if ( LbFiles.Items[i].Selected )
{
DeleteFile( LbFiles.Items[i].Text );
LbFiles.Items.Remove( LbFiles.Items[i] );
}
}
}
}
}