原理:asp.net上传附件用的是HtmlInputFile 控件,此控件的一个最重要的属性PostedFile,用来获取用户上传的附件,其类型为HttpPostFile。 当每次添加附件,形成回发,HtmlInputFile的属性postedfile都会有一个新值,所以正常情况下不能附加多个附件,但是若让每次添加附件的时候,把起属性postedfile的HttpPostFile实例对象存其来,等到提交是一起存储,就能实现多文件上传,而这些HttpPostFile对象的存储容器就是集合ArrayList,存储的地方是在Session中.
实现:声明一个集合类的对象 postfiels,添加附件时,把附件的PostedFile属性(其实是一个HttpPostedFile实例)添加到集合中。当上传时,遍历集合,对每个HttpPostedFile进行SaveAs操作,就可以实现多文件的上传了。 另外,最好和一些控件如:DropDownList或其他控件一起使用,这样用户可以知道自己上传了多少和上传了什么文件。
部分代码:
1
public
void
Addfile(System.Web.HttpPostedFile postfile,
ref
System.Web.UI.WebControls.DropDownList drop)
2 {
3
4 if (postfile.FileName != null )
5 {
6 System.Collections.ArrayList postfiles;
7 HttpContext context = HttpContext.Current;
8 if (context.Session[ " postfiles " ] == null )
9 {
10 postfiles = new System.Collections.ArrayList();
11 }
12 else
13 {
14 postfiles = (System.Collections.ArrayList)context.Session[ " postfiles " ];
15 }
16
17 postfiles.Add(postfile);
18 context.Session[ " postfiles " ] = postfiles;
19 System.Web.UI.WebControls.ListItem item = new System.Web.UI.WebControls.ListItem();
20 item.Text = postfile.FileName.Substring(postfile.FileName.LastIndexOf( " \\ " ) + 1 );
21 drop.Items.Add(item);
22 }
2 {
3
4 if (postfile.FileName != null )
5 {
6 System.Collections.ArrayList postfiles;
7 HttpContext context = HttpContext.Current;
8 if (context.Session[ " postfiles " ] == null )
9 {
10 postfiles = new System.Collections.ArrayList();
11 }
12 else
13 {
14 postfiles = (System.Collections.ArrayList)context.Session[ " postfiles " ];
15 }
16
17 postfiles.Add(postfile);
18 context.Session[ " postfiles " ] = postfiles;
19 System.Web.UI.WebControls.ListItem item = new System.Web.UI.WebControls.ListItem();
20 item.Text = postfile.FileName.Substring(postfile.FileName.LastIndexOf( " \\ " ) + 1 );
21 drop.Items.Add(item);
22 }
其中,第一个参数是HtmlInputFil的属性PostedFile,第二个参数是一个下拉列表控件,用来显示用户的已经上传的附件。并且,每次把附件的附件名(HtmlInputFil的FileName属性)添加到下拉列表的一个单元的text中
上传函数:
1
public
string
Upfiles(
string
path,
string
prefix,
ref
System.Web.UI.WebControls.DropDownList drop)
2 {
3 HttpContext context = HttpContext.Current;
4 if (context.Session[ " postfiles " ] != null )
5 {
6 System.Text.StringBuilder strb_filenames = new StringBuilder(); // 用来存储附件名,用","分割;
7 strb_filenames.Append( " ' " );
8 System.Collections.ArrayList files = (System.Collections.ArrayList)context.Session[ " postfiles " ];
9 foreach (System.Web.HttpPostedFile pfile in files)
10 {
11 string sfilename = pfile.FileName.Substring(pfile.FileName.LastIndexOf( " \\ " ) + 1 );
12 pfile.SaveAs(path + prefix + sfilename);
13 strb_filenames.Append((prefix + sfilename) + " , " );
14 }
15 drop.Items.Clear();
16 strb_filenames.Append( " ' " );
17 return strb_filenames.ToString();
18 }
19 else
20 {
21 return null ;
22 }
23 }
2 {
3 HttpContext context = HttpContext.Current;
4 if (context.Session[ " postfiles " ] != null )
5 {
6 System.Text.StringBuilder strb_filenames = new StringBuilder(); // 用来存储附件名,用","分割;
7 strb_filenames.Append( " ' " );
8 System.Collections.ArrayList files = (System.Collections.ArrayList)context.Session[ " postfiles " ];
9 foreach (System.Web.HttpPostedFile pfile in files)
10 {
11 string sfilename = pfile.FileName.Substring(pfile.FileName.LastIndexOf( " \\ " ) + 1 );
12 pfile.SaveAs(path + prefix + sfilename);
13 strb_filenames.Append((prefix + sfilename) + " , " );
14 }
15 drop.Items.Clear();
16 strb_filenames.Append( " ' " );
17 return strb_filenames.ToString();
18 }
19 else
20 {
21 return null ;
22 }
23 }
上传函数从会话中提取附件集合,并存储每个文件,让后将所有文件的文件名返回,以便将其存入数据库,另外,每次调用完上传函数后,一定要记得删除会话中的集合对象!!!否则,内存会急剧减少!
这个方法有个很大的缺点就是1耗内存,2由于集合对象无法序列化,所以webconfig中的session模式必须设置成InProc模式,不能用服务器和SQl模式。
我正想法做直接从客户端读取流的方法来上传附件,目前没有作出,呵呵
若有好的办法,欢迎赐教!!