应用程序中经常需要允许用户把文件上传到web服务器
尽管在ASP
NET
X也可以完成该功能
但在ASP
NET
中使用FileUpload控件会更简单
该控件让用户更容易地浏览和选择用于上传的文件它包含一个浏览按钮和用于输入文件名的文本框只要用户在文本框中输入了完全限定的文件名无论是直接输入或通过浏览按钮选择都可以调用FileUpload的SaveAs方法保存到磁盘上
除了从WebControl类继承的标准成员FileUpload控件还公开了几个只读的属性在表和表列出
表 FileUpload控件属性
名 称 类型 读 写 说 明 FileContent Stream × 返回一个指向上传文件的流对象 FileName string × 返回要上传文件的名称不包含路径信息 HasFile Boolean × 如果是true则表示该控件有文件要上传 PostedFile HttpPostedFile × 返回已经上传文件的引用表列出了它所公开的只读属性
表 HttpPostedFile属性
名 称 类 型 读 写 说 明 ContentLength integer × 返回上传文件的按字节表示的文件大小 ContentType string × 返回上传文件的MIME内容类型 FileName string × 返回文件在客户端的完全限定名 InputStream Stream × 返回一个指向上传文件的流对象
所有这些属性将在下面的示例中说明
为了查看FileUpload控件在实际中的运用创建一个FileUploadDemo网站在页面上添加一个FileUpload控件然后添加两个ASPNET按钮Text属性分别设置为Save和DisplayID分别设置为btnSave和btnDisplay增加两个Label控件并分别将ID设置为lblMesage和lblDisplay用<br/>HTML元素分隔这些控件切换到设计视图通过双击每个按钮为它们在代码隐藏文件中创建具有默认名称的Click事件处理程序完成后的内容文件类似于示例
示例FileUploadDemo网站的defaultaspx
<%@ Page Language=C# AutoEventWireup=true CodeFile=Defaultaspxcs Inherits=_Default %>
<!DOCTYPE html PUBLIC //WC//DTD XHTML //EN >
<html xmlns= >
<head runat=server>
<title>FileUpload Control</title>
</head>
<body>
<form id=form runat=server>
<div>
<h>FileUpload Control</h>
<asp:FileUpload ID=FileUpload runat=server />
<br />
<asp:Button ID=btnSave runat=server Text=Save OnClick=btnSave_Click />
<asp:Button ID=btnDisplay runat=server Text=Display OnClick=btnDisplay_Click />
<br />
<br />
<asp:Label ID=lblMessage runat=server />
<asp:Label ID=lblDisplay runat=server />
</div>
</form>
</body>
</html>
在代码隐藏文件中添加示例中高亮显示的代码非高亮显示的代码由VS自动创建
示例FileUploadDemo网站的Defaultaspxcs
using System;
using SystemData;
using SystemConfiguration;
using SystemWeb;
using SystemWebSecurity;
using SystemWebUI;
using SystemWebUIWebControls;
using SystemWebUIWebControlsWebParts;
using SystemWebUIHtmlControls;
using SystemIO; // 使用Stream必需
public partial class _Default : SystemWebUIPage
{
protected void Page_Load(object sender EventArgs e)
{}
protected void btnSave_Click(object sender EventArgs e)
{
string str = ;
if (FileUploadHasFile)
{
try
{
str += Uploading file: + FileUploadFileName;
// 保存文件
FileUploadSaveAs(c:\\websites\\uploads\\ + FileUploadFileName);
// 显示文件信息
str += <br/>Saved As: + FileUploadPostedFileFileName;
str += <br/>File Type: + FileUploadPostedFileContentType;
str += <br/>File Length (bytes): + FileUploadPostedFileContentLength;
str += <br/>PostedFile File Name: + FileUploadPostedFileFileName;
}
catch (Exception ex)
{
str += <br/><b>Error</b><br/>Unable to save
c:\\websites\\uploads\\ + FileUploadFileName +<br/> + exMessage;
}
}
else
{
str = No file uploaded;
}
lblMessageText = str;
lblDisplayText = ;
}
protected void btnDisplay_Click(object sender EventArgs e)
{
string str = <u>File: + FileUploadFileName + </u><br/>;
if (FileUploadHasFile)
{
try
{
Stream stream = FileUploadFileContent;
StreamReader reader = new StreamReader(stream);
string strLine = ;
do
{
strLine = readerReadLine( );
str += strLine;
} while (strLine != null);
}
catch (Exception ex)
{
str += <br/><b>Error</b><br/>Unable to display + FileUploadFileName +
<br/> + exMessage;
}
}
else
{
str = No file uploaded;
}
lblDisplayText = str;
lblMessageText = ;
}
}
高亮显示的using声明对于不使用完全限定命名空间而使用Stream对象是必须的
在Save按钮的btnSave_Click事件处理程序中FileUpload控件的HasFile属性用于检测文本框中是否输入了有效的完全限定文件名如果文本框为空或输入的名称无效将不会通过检测并且lblMessage将显示No file upladed
假定上传了一个有效文件那么将执行try代码块中的代码关键语句是调用File Upload控件的SaveAs方法该方法使用硬编码路径和FileName属性传递一个完全限定的文件名该语句可能会由于各种原因而失败包括磁盘空间不足无效的路径或安全问题(稍后会有更详细的说明)
如果SaveAs方法失败则执行catch代码块在lblMessage中显示一个错误信息包括该异常的Message属性exMessage
如果SaveAs方法执行成功关于上传文件的多个信息将显示在lblMessage中这些信息通过FileUploadPostedFile(类型为HttpPostedFile)中的属性获取
Display按钮的Click事件处理程序与前面的类似只不过它不是显示文件信息而是显示文件内容它通过使用FileContent属性获取表现为Stream对象的上传文件的内容然后这个Stream对象被用于实例化一个StreamReader对象StreamReader的Read Line方法逐行的遍历文件然后把合并后的字符串显示在lblDisplay中
当在讨论从客户端上传文件到web服务器时安全是非常让人关注的须注意两点首先使用这种方式会公开web服务器从而会有非常大的安全漏洞为此要特别细心因为这样不仅可以上传病毒木马和其他恶意软件还会存在客户端浏览web服务器目
录结构的危险因此应该使用硬编码目标目录至少严格限定在哪里保存上传的文件
另外要注意的一点是允许在磁盘写文件所必需的权限在开发web应用程序时一般情况下开发机器同时也是web服务器特别是使用VS默认的开发模式在该模式下使用的是内置的web服务器并且不通过IIS访问网站而是由文件系统访问网站这样永远也不会有权限问题
然而当网站部署到产品服务器上且该网站通过IIS和虚拟目录来访问时就会出现问题这是因为运行ASPNET的账户必须拥有对用于保存上传文件的目录的写权限在Windows/XP中账户的名称是ASPNET在Windows Server中写权限必须分配给IIS_WPG账户组
利用FileUpload控件并结合良好的安全防护用户可以把自己的文件传送到网站以丰富网站功能