首页 > 编程 > .NET > 正文

ASP.NET 2.0高级控件之FileUpload控件

2024-07-10 13:09:06
字体:
来源:转载
供稿:网友

  应用程序中经常需要允许用户把文件上传到web服务器。尽管在asp.net 1.x也可以完成该功能,但在asp.net 2.0中使用fileupload控件会更简单。

  该控件让用户更容易地浏览和选择用于上传的文件,它包含一个浏览按钮和用于输入文件名的文本框。只要用户在文本框中输入了完全限定的文件名,无论是直接输入或通过浏览按钮选择,都可以调用fileupload的saveas方法保存到磁盘上。

  除了从webcontrol类继承的标准成员,fileupload控件还公开了几个只读的属性,在表5-8和表5-9列出。

  表5-8 fileupload控件属性

名  称 类型 说  明
filecontent stream × 返回一个指向上传文件的流对象
filename string × 返回要上传文件的名称,不包含路径信息
hasfile boolean × 如果是true,则表示该控件有文件要上传
postedfile httppostedfile × 返回已经上传文件的引用。表5-9列出了它所公开的只读属性

  表5-9 httppostedfile属性

名  称 类  型 说  明
contentlength integer × 返回上传文件的按字节表示的文件大小
contenttype string × 返回上传文件的mime内容类型
filename string × 返回文件在客户端的完全限定名
inputstream stream × 返回一个指向上传文件的流对象

  所有这些属性将在下面的示例中说明。

  为了查看fileupload控件在实际中的运用,创建一个fileuploaddemo网站。在页面上添加一个fileupload控件,然后,添加两个asp.net按钮,text属性分别设置为save和display,id分别设置为btnsave和btndisplay。增加两个label控件,并分别将id设置为lblmesage和lbldisplay。用<br/>html元素分隔这些控件。切换到设计视图,通过双击每个按钮,为它们在代码隐藏文件中创建具有默认名称的click事件处理程序。完成后的内容文件类似于示例5-11。

  示例5-11:fileuploaddemo网站的default.aspx

<%@ page language=”c#” autoeventwireup=”true” codefile=”default.aspx.cs” inherits=”_default” %>
<!doctype html public “-//w3c//dtd xhtml 1.1//en” “http://www.w3.org/tr/xhtml11/dtd/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
 <title>fileupload control</title>
</head>

<body>
 <form id=”form1” runat=”server”>
 <div>
  <h1>fileupload control</h1>
  <asp:fileupload id=”fileupload1” 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>

  在代码隐藏文件中,添加示例5-12中高亮显示的代码,非高亮显示的代码由vs2005自动创建。

  示例5-12:fileuploaddemo网站的default.aspx.cs

using system;
using system.data;
using system.configuration;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
using system.io; // 使用stream必需

public partial class _default : system.web.ui.page
{
 protected void page_load(object sender, eventargs e)
 {}
 protected void btnsave_click(object sender, eventargs e)
 {
  string str = “”;
  if (fileupload1.hasfile)
  {
   try
   {
    str += “uploading file: “ + fileupload1.filename;
    // 保存文件
    fileupload1.saveas(“c://websites//uploads//” + fileupload1.filename);
    // 显示文件信息
    str += “<br/>saved as: “ + fileupload1.postedfile.filename;
    str += “<br/>file type: “ + fileupload1.postedfile.contenttype;
    str += “<br/>file length (bytes): “ + fileupload1.postedfile.contentlength;
    str += “<br/>postedfile file name: “ + fileupload1.postedfile.filename;
   }
   catch (exception ex)
   {
    str += “<br/><b>error</b><br/>unable to save
c://websites//uploads//” + fileupload1.filename +“<br/>” + ex.message;
   }
  }
  else
  {
   str = “no file uploaded.”;
  }
  lblmessage.text = str;
  lbldisplay.text = “”;
 }

 protected void btndisplay_click(object sender, eventargs e)
 {
  string str = “<u>file: “ + fileupload1.filename + “</u><br/>”;
  if (fileupload1.hasfile)
  {
   try
   {
    stream stream = fileupload1.filecontent;
    streamreader reader = new streamreader(stream);
    string strline = “”;
    do
    {
     strline = reader.readline( );
     str += strline;
    } while (strline != null);
   }
   catch (exception ex)
   {
    str += “<br/><b>error</b><br/>unable to display “ + fileupload1.filename +
“<br/>” + ex.message;
   }
  }
  else
  {
   str = “no file uploaded.”;
  }
  lbldisplay.text = str;
  lblmessage.text = “”;
 }
}

  高亮显示的using声明对于不使用完全限定命名空间,而使用stream对象是必须的。

  在save按钮的btnsave_click事件处理程序中,fileupload控件的hasfile属性用于检测文本框中是否输入了有效的完全限定文件名。如果文本框为空或输入的名称无效,将不会通过检测,并且lblmessage将显示“no file upladed”。

  假定上传了一个有效文件,那么将执行try代码块中的代码。关键语句是调用file- upload控件的saveas方法。该方法使用硬编码路径和filename属性传递一个完全限定的文件名。该语句可能会由于各种原因而失败,包括磁盘空间不足、无效的路径或安全问题(稍后会有更详细的说明)。

  如果saveas方法失败,则执行catch代码块。在lblmessage中显示一个错误信息,包括该异常的message属性ex.message。

  如果saveas方法执行成功,关于上传文件的多个信息将显示在lblmessage中,这些信息通过fileupload.postedfile(类型为httppostedfile)中的属性获取。

  display按钮的click事件处理程序与前面的类似,只不过它不是显示文件信息,而是显示文件内容。它通过使用filecontent属性获取表现为stream对象的上传文件的内容,然后这个stream对象被用于实例化一个streamreader对象。streamreader的read- line方法逐行的遍历文件,然后把合并后的字符串显示在lbldisplay中。

  当在讨论从客户端上传文件到web服务器时,安全是非常让人关注的。须注意两点,首先,使用这种方式会公开web服务器,从而会有非常大的安全漏洞,为此要特别细心。因为这样不仅可以上传病毒,木马和其他恶意软件,还会存在客户端浏览web服务器目

  录结构的危险。因此,应该使用硬编码目标目录,至少严格限定在哪里保存上传的文件。

  另外,要注意的一点是,允许在磁盘写文件所必需的权限。在开发web应用程序时,一般情况下,开发机器同时也是web服务器,特别是使用vs2005默认的开发模式。在该模式下使用的是内置的web服务器,并且不通过iis访问网站而是由文件系统访问网站。这样,永远也不会有权限问题。

  然而,当网站部署到产品服务器上,且该网站通过iis和虚拟目录来访问时,就会出现问题。这是因为运行asp.net的账户必须拥有对用于保存上传文件的目录的写权限。在windows2000/xp中,账户的名称是aspnet。在windows server2003中,写权限必须分配给iis_wpg账户组。

  利用fileupload控件并结合良好的安全防护,用户可以把自己的文件传送到网站,以丰富网站功能。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表