FileUpload 服务器控件示例

转载 2006年06月01日 16:44:00

简介

自引入 Microsoft ASP.NET 版本 1.0 之日起,就存在生成 Web 应用程序的内置方法,这些方法能够将文件上载到宿主服务器。这是通过使用 File Field HTML 服务器控件实现的。我以前写过一篇关于如何在 ASP.NET 应用程序中有效使用该控件的 MSDN 文章。本文将再次介绍文件上载过程,但不是使用 File Field 控件,我将向您介绍如何有效使用 ASP.NET 2.0 提供的新 FileUpload 服务器控件。

虽然本文向您介绍新增的 FileUpload 服务器控件,但现在仍然可以在应用程序中使用 File Field 控件,注意到这一点是非常重要的。

FileUpload 服务器控件示例

在 ASP.NET 1.x 中使用 File Field 控件时,必须采取一些额外的步骤才能使一切有条不紊地正常运行。例如,您需要亲自将 enctype="multipart/form-data" 添加到页面的 <form> 元素中。ASP.NET 2.0 中提供的新 FileUpload 服务器控件使将文件上载到宿主服务器的过程尽可能的简单。

最后,您试图允许对 HTML <input type="file">标记进行编程。该标记用于与 HTML 窗体中的文件数据一起使用。过去使用传统的 ASP(ASP 3.0 或更早的版本)时,许多程序员使用第三方组件将文件从客户端上载到服务器。现在,通过 .NET 和该新控件可以进行上载。清单 1 显示如何使用 FileUpload 控件将文件上载到服务器。

提供 Microsoft Visual Basic 和 C# 形式的示例代码。

清单 1. 使用 FileUpload 控件将文件上载到服务器

Visual Basic

<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
If FileUpload1.HasFile Then
Try
FileUpload1.SaveAs("C:/Uploads/" & _
FileUpload1.FileName)
Label1.Text = "File name: " & _
FileUpload1.PostedFile.FileName & "<br>" & _
"File Size: " & _
FileUpload1.PostedFile.ContentLength & " kb<br>" & _
"Content type: " & _
FileUpload1.PostedFile.ContentType
Catch ex As Exception
Label1.Text = "ERROR: " & ex.Message.ToString()
End Try
Else
Label1.Text = "You have not specified a file."
End If
End Sub
</script>

<HTML xmlns="http://www.w3.org/1999/xHTML" >
<head runat="server">
<title>Upload Files</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ASP:FileUpload ID="FileUpload1" runat="server" /><br />
<br />
<ASP:Button ID="Button1" runat="server" OnClick="Button1_Click"
Text="Upload File" /> <br />
<br />
<ASP:Label ID="Label1" runat="server"></ASP:Label></div>
</form>
</body>
</HTML>

C#

<%@ Page Language="C#" %>
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
try
{
FileUpload1.SaveAs("C://Uploads//" +
FileUpload1.FileName);
Label1.Text = "File name: " +
FileUpload1.PostedFile.FileName + "<br>" +
FileUpload1.PostedFile.ContentLength + " kb<br>" +
"Content type: " +
FileUpload1.PostedFile.ContentType;
}
catch (Exception ex)
{
Label1.Text = "ERROR: " + ex.Message.ToString();
}
else
{
Label1.Text = "You have not specified a file.";
}
}
</script>

<HTML xmlns="http://www.w3.org/1999/xHTML" >
<head runat="server">
<title>Upload Files</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ASP:FileUpload ID="FileUpload1" runat="server" /><br />
<br />
<ASP:Button ID="Button1" runat="server" OnClick="Button1_Click"
Text="Upload File" /> <br />
<br />
<ASP:Label ID="Label1" runat="server"></ASP:Label></div>
</form>
</body>
</HTML>

运行该页,如果看看为该页生成的源代码,就会注意到一些问题。清单 2 列出这段源代码。

清单 2. FileUpload 控件生成的源代码

<HTML xmlns="http://www.w3.org/1999/xHTML" >
<head><title>
Upload Files
</title></head>
<body>
<form name="form1" method="post" action="MyFileUpload.ASPx"
id="form1" enctype="multipart/form-data">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNDcxNTg5NDg3D2QWAgIEDxYCHgdlbmN0eXBlBRNtdWx0aXBhcnQvZm9yb
S1kYXRhZGQUQEUFMY1+/fp1mnrkbqmVNQIzFA==" />
</div>

<div>
<input type="file" name="FileUpload1" id="FileUpload1" /><br />
<br />
<input type="submit" name="Button1" value="Upload File"
id="Button1" /> <br />
<br />
<span id="Label1"></span>
</div>

<div>

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEWAgLB+7jIAwKM54rGBv2Iz6LxVY7jWec0gZMxnuaK2ufq" />
</div></form>
</body>
</HTML>

首先要注意的是,由于 FileUpload 控件位于该页上,因此 ASP.NET 2.0 通过添加相应的 enctype 属性来代替您修改该页的 <form> 元素。您还会注意到,FileUpload 控件被转换为一个 HTML <input type="file">元素。

清单 1 中的页面运行后,您可以选择一个文件,然后通过单击该页上的 Upload File 按钮将它上载到服务器。针对该示例,我们需要重温一些重要的事项,以便理解实现该操作所需的所有步骤。要使清单 1 中的示例生效,必须使服务器上的目标文件夹对于 ASP.NET 使用的帐户是可写的,这样才能将文件保存到指定的文件夹中。

如果您认为自己的 ASP.NET 帐户不能写入希望的文件夹,则只需打开 Microsoft Windows Explorer,然后定位到要添加该权限的文件夹即可。右击该文件夹(本例中为 Uploads 文件夹),然后选择 Properties。在 Properties 对话框中,单击 Security 选项卡,确保列表中包括 ASP.NET 机器帐户,该帐户具有写入磁盘的适当权限(请参见图 1)。


图 1. 查看 Uploads 文件夹的 Security 选项卡

 

如果在 Security 选项卡下没看到 ASP.NET 机器帐户,可以通过单击 Add 按钮并在文本区域中输入 ASPNET(没有期限)来添加该帐户,如图 2 所示。


图 2. 将 ASP.NET 机器帐户添加到文件夹安全性定义中

 

单击 OK,将 ASP.NET 机器帐户添加到列表中。在此,请确保为该帐户赋予了适当的权限,然后单击 OK,这样就准备就绪了。

该页上的 Submit 按钮会引发 Button1_Click 事件发生。该事件上载文件,然后显示一条消息,通过发布有关已上载文件的信息来告诉您上载是否成功。如果上载失败,则该页显示一条描述上载失败原因的错误消息。

通过使用将自己转换为<input type="file"> 标记的 FileUpload 控件,浏览器自动将一个 Browse 按钮放在 ASP.NET 页上的文本字段旁边。无需进行任何编程,就会出现这种情况。当最终用户单击 Browse 按钮时,他可以浏览本地文件系统以查找要上载到服务器的文件。如图 3 所示。单击 Open 将把文件名和该文件的路径放到文本字段中。


图 3. 选择文件

 

解决文件大小限制

您可能没意识到,但对于可以使用该技术上载的文件的大小存在限制。默认情况下,使用 FileUpload 控件上载到服务器的文件最大为 4MB 左右。不能上载超过该限制的任何内容。

然而,关于 .NET 的重要一点是,它通常会提供一种规避限制的方法。您通常可以更改正在使用的默认设置。要更改大小限制,可以在 web.config.comments 文件(可以在 C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/CONFIG 的 ASP.NET 2.0 配置文件夹中找到)或应用程序的 web.config 文件中进行一些改动。

在 web.config.comments 文件中,查找一个名为 <executionTimeout>的节点,如下所示:

<httpRuntime 
executionTimeout="110"
maxRequestLength="4096"
requestLengthDiskThreshold="80"
useFullyQualifiedRedirectUrl="false"
minFreeThreads="8"
minLocalRequestFreeThreads="4"
appRequestQueueLimit="5000"
enableKernelOutputCache="true"
enableVersionHeader="true"
requireRootedSaveASPath="true"
enable="true"
shutdownTimeout="90"
delayNotificationTimeout="5"
waitChangeNotification="0"
maxWaitChangeNotification="0"
enableHeaderChecking="true"
sendCacheControlHeader="true"
apartmentThreading="false" />

在这个节点上进行了许多操作,但负责上载文件大小的设置是 maxRequestLength 属性。默认情况下,该属性设置为 4096 千字节 (KB)。只需更改此值,就可以增加可上载到服务器的文件大小。如果想要允许将 10 兆字节 (MB) 的文件上载到服务器,则将 maxRequestLength 值设置为 11264,这意味着该应用程序允许将最大为 11000 KB 的文件上载到服务器。

在 web.config.comments 文件中进行此改动会将该设置应用于服务器上的所有应用程序。如果要将该设置仅应用于正在使用的应用程序,则将该节点应用于应用程序的 web.config 文件,覆盖 web.config.comments 文件中的所有设置。请确保该节点位于配置文件中的 <system.web> 节点之间。

与上载文件大小限制有关的另一个设置是赋给 <httpRuntime> 节点中 executionTimeout 属性的值。

赋给 executionTimeout 属性的值是 ASP.NET 关闭前允许发生的上载秒数。如果要允许将更大的文件上载到服务器,则还要增加该值和 maxRequestLength 值。

增加可上载文件大小的一个缺点是,存在通过发出大量请求来攻击服务器的黑客。要避免这种情况,可以减小允许上载的文件大小;否则,可能会发现数百个甚至上千个 10 MB 的请求访问您的服务器。

客户端验证允许上载的文件类型

有几种方法可以用来控制上载到服务器的文件类型。遗憾的是,没有一种十全十美的方法可以防御其他人上载恶意的文件。然而,您可以采取一些步骤,以使这个允许最终用户上载文件的过程更易于管理。

一个可用的好方法是使用 ASP.NET 免费提供的 ASP.NET 验证控件。这些控件使您可以对正在上载的文件进行正则表达式检查,看看文件的扩展名是否在允许上载的扩展名之列。

因为该方法强制在客户端进行检查,所以对于允许在客户端使用验证控件的浏览器而言,这是一个理想的选择;如果签名不是您允许的签名,则该文件不能上载到服务器。清单 3 显示一个使用验证控件完成该任务的示例。

此处不介绍验证控件的用法。有关验证控件的完整解释以及如何在 ASP.NET 页中使用它们,请参阅 Validating ASP.NET Server Controls

清单 3. 使用验证控件限制上载到服务器的文件类型

<ASP:FileUpload ID="FileUpload1" runat="server" /><br />
<br />
<ASP:Button ID="Button1" runat="server" OnClick="Button1_Click"
Text="Upload File" /> <br />
<br />
<ASP:Label ID="Label1" runat="server"></ASP:Label>
<ASP:RegularExpressionValidator
id="RegularExpressionValidator1" runat="server"
ErrorMessage="Only mp3, m3u or mpeg files are allowed!"
ValidationExpression="^(([a-zA-Z]:)|(//{2}/w+)/$?)(//(/w[/w].*))
+(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)___FCKpd___4quot;
ControlToValidate="FileUpload1"></ASP:RegularExpressionValidator>
<br />
<ASP:RequiredFieldValidator
id="RequiredFieldValidator1" runat="server"
ErrorMessage="This is a required field!"
ControlToValidate="FileUpload1"></ASP:RequiredFieldValidator>

这个简单的 ASP.NET 页使用验证控件,这样最终用户就只能将 .mp3、.mpeg 或 .m3u 文件上载到服务器。如果文件类型不是以上可选的文件类型,则 Validation 控件向屏幕抛出一个异常。如图 4 所示。


图 4. 使用验证控件验证文件类型

 

对于上载到服务器的文件,使用 Validation 控件不是一个对其进行控制的有效方法。更改一个文件的文件扩展名并不太困难,因此扩展名将被接受并上载到服务器,从而可以避开这个简单的安全模型。

增加服务器端文件类型验证

您刚才看到一种将一些 ASP.NET 验证服务器控件添加到 ASP.NET 页,以便在客户端对文件扩展名进行验证(以文本方式)的简单方法。现在,让我们看看如何在服务器端执行类似的操作。如清单 4 所示。

清单 4. 检查服务器上的文件类型

Visual Basic

    Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
If FileUpload1.HasFile Then
Dim fileExt As String
fileExt = System.IO.Path.GetExtension(FileUpload1.FileName)

If (fileExt = ".mp3") Then
Try
FileUpload1.SaveAs("C:/Uploads/" & _
FileUpload1.FileName)
Label1.Text = "File name: " & _
FileUpload1.PostedFile.FileName & "" & _
"File Size: " & _
FileUpload1.PostedFile.ContentLength & " kb" & _
"Content type: " & _
FileUpload1.PostedFile.ContentType
Catch ex As Exception
Label1.Text = "ERROR: " & ex.Message.ToString()
End Try
Else
Label1.Text = "Only .mp3 files allowed!"
End If
Else
Label1.Text = "You have not specified a file."
End If
End Sub

C#

    protected void Button1_Click(object sender, EventArgs e)
{

if (FileUpload1.HasFile)
{
string fileExt =
System.IO.Path.GetExtension(FileUpload1.FileName);

if (fileExt == ".mp3")
{
try
{
FileUpload1.SaveAs("C://Uploads//" +
FileUpload1.FileName);
Label1.Text = "File name: " +
FileUpload1.PostedFile.FileName + "" +
FileUpload1.PostedFile.ContentLength + " kb" +
"Content type: " +
FileUpload1.PostedFile.ContentType;
}
catch (Exception ex)
{
Label1.Text = "ERROR: " + ex.Message.ToString();
}
}
else
{
Label1.Text = "Only .mp3 files allowed!";
}
}
else
{
Label1.Text = "You have not specified a file.";
}
}

现在,通过在 System.IO.Path 命名空间中使用 GetExtension 方法,基本可以执行相同的操作。对于最终用户而言,只需将文件扩展名更改为可以生效的名称并将更改的文件上载到宿主服务器的功能不会有所影响,注意到这一点非常重要。

同时上载多个文件

目前为止,已经有几个不错的示例说明了如何不费周折地将文件上载到服务器。现在,让我们看看如何从一个页面将多个文件上载到服务器。

Microsoft .NET Framework 中没有任何内置功能使您可以从一个 ASP.NET 页上载多个文件。然而,只需要少量工作,您就可以像过去使用 .NET 1.x 那样完成此任务。

方法是将 System.IO 类导入到 ASP.NET 页中,然后使用 HttpFileCollection 类捕获通过 Request 对象发送来的所有文件。该方法使您可以从一个页面上载所需数量的文件。

如果需要,您完全可以分别处理该页上的每个 FileUpload 控件,如清单 5 所示。

清单 5. 分别处理每个 FileUpload 控件

Visual Basic

If FileUpload1.HasFile Then
' Handle file
End If

If FileUpload2.HasFile Then
' Handle file
End If

C#

if (FileUpload1.HasFile) {
// Handle file
}

if (FileUpload2.HasFile) {
// Handle file
}

该方法有效,但可能存在这种情况:您要使用 HttpFileCollection 类处理文件,特别是在处理动态生成的服务器控件列表时。

针对这种情况的示例,您可以生成一个 ASP.NET 页,该页有三个 FileUpload 控件和一个 Submit 按钮(使用 Button 控件)。用户单击 Submit 按钮并且文件被发布到服务器之后,隐藏的代码将文件保存到服务器上的特定位置。保存文件后,在 ASP.NET 页上显示已发布的文件信息(请参见清单 6)。

清单 6. 将多个文件上载到服务器

Visual Basic

Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)

Dim filepath As String = "C:/Uploads"
Dim uploadedFiles As HttpFileCollection = Request.Files
Dim i As Integer = 0

Do Until i = uploadedFiles.Count
Dim userPostedFile As HttpPostedFile = uploadedFiles(i)

Try
If (userPostedFile.ContentLength > 0) Then
Label1.Text += "File #" & (i + 1) & ""
Label1.Text += "File Content Type: " & _
userPostedFile.ContentType & ""
Label1.Text += "File Size: " & _
userPostedFile.ContentLength & "kb"
Label1.Text += "File Name: " & _
userPostedFile.FileName & ""

userPostedFile.SaveAs(filepath & "/" & _
System.IO.Path.GetFileName(userPostedFile.FileName))

Label1.Text += "Location where saved: " & _
filepath & "/" & _
System.IO.Path.GetFileName(userPostedFile.FileName) & _
"
"
End If
Catch ex As Exception
Label1.Text += "Error:" & ex.Message
End Try
i += 1
Loop
End Sub

C#

protected void Button1_Click(object sender, EventArgs e)
{
string filepath = "C://Uploads";
HttpFileCollection uploadedFiles = Request.Files;

for (int i = 0; i < uploadedFiles.Count; i++)
{
HttpPostedFile userPostedFile = uploadedFiles[i];

try
{
if (userPostedFile.ContentLength > 0 )
{
Label1.Text += "File #" + (i+1) +
"";
Label1.Text += "File Content Type: " +
userPostedFile.ContentType + "";
Label1.Text += "File Size: " +
userPostedFile.ContentLength + "kb";
Label1.Text += "File Name: " +
userPostedFile.FileName + "";

userPostedFile.SaveAs(filepath + "//" +
System.IO.Path.GetFileName(userPostedFile.FileName));

Label1.Text += "Location where saved: " +
filepath + "//" +
System.IO.Path.GetFileName(userPostedFile.FileName) +
"
";
}
}
catch (Exception Ex)
{
Label1.Text += "Error: " + Ex.Message;
}
}
}

最终用户最多可以选择四个文件,然后单击 Upload Files 按钮,该按钮会初始化 Button1_Click 事件。使用 HttpFileCollection 类和 Request.Files 属性使您可以控制从该页上载的所有文件。当这些文件处于此状态时,您可以对它们进行任何操作。在本例中,检查文件的属性并将它们输出到屏幕上。最后,这些文件保存到服务器根目录的 Uploads 文件夹中。该操作的结果如图 5 所示。


图 5. 一次将一个 ASP.NET 页上的四个文件上载到服务器

 

您可能已经注意到,该示例有趣的一点是,文件输入文本框的状态没有通过回发进行保存。在图 5 中您可以看到这一点。在 ASP.NET 中,无法保存文件输入文本框的状态,因为这么做可能会引发安全风险。

小结

ASP.NET 提供的 FileUpload 服务器控件是一个强大的控件,在 Active Server Pages 3.0 时代实现该控件非常困难。这个新增的功能允许最终用户将一个或多个文件上载到服务器。请记住,通过利用 web.config.comments 或 web.config 文件中的设置,您可以控制文件的大小。

使用input代替服务器控件FileUpload实现文件上传

最近做一个项目后台发布系统,大致上是使用Jquer插件layer.js、Jquery与一般处理程序实现参数传递数据库及页面交互 下面是使用jquery.form.js插件给一般处理程序传递参数,实现...
  • CGS_______
  • CGS_______
  • 2016年11月02日 22:03
  • 1337

【转载】FileUpload控件上传文件示例

【转载】FileUpload控件上传文件示例   前台代码:添加FileUpload控件和Lable控件以及Button按钮控件     FileUpload上...
  • a6225301
  • a6225301
  • 2014年02月04日 10:37
  • 4301

FileUpload 服务器控件上载文件

FileUpload 服务器控件示例在 ASP.NET 1.x 中使用 File Field 控件时,必须采取一些额外的步骤才能使一切有条不紊地正常运行。例如,您需要亲自将 enctype="mult...
  • youxinqiang
  • youxinqiang
  • 2007年09月30日 13:58
  • 591

ASP.net MVC FileUpload 文件上传

ASP.net MVC的上传文件功能并没有其他模块(action,Controller)那么智能、好用,不过也不是很复杂。打开vs2008 新建一个MVC工程 如果web项目没有asp.net mvc...
  • ol_beta
  • ol_beta
  • 2010年04月06日 10:40
  • 13483

[C#]怎样自定义一个服务器端的控件

  大家知道在ASP.NET中微软为我们提供了大量的服务器端控件,包括HtmlControl 和WebControl。它们功能强大,为我们的编程提供了极大的方便。更重要的一点是它开放了对第三方控件的使...
  • kenter78
  • kenter78
  • 2005年03月10日 10:04
  • 900

利用commons-fileupload组件实现文件上传-实例

一、所需要的包: 1、commons-fileupload-1.2.1.jar: 下载地址 http://commons.apache.org/downloads/download_fi...
  • elong490
  • elong490
  • 2014年11月18日 17:45
  • 2727

ASP.NET自定义服务器控件

最简单的服务器端控件开发流程简介。
  • yanwushu
  • yanwushu
  • 2014年04月08日 21:34
  • 4387

VS中“ASP.NET服务器控件”

最近在看关于ASP.NET方面的知识,很有自知之明地从基础做起,下面是查的一些东西,记不住先总结成博客,以后查看,起风~~~~ using System; using System.Collecti...
  • ma15732625261
  • ma15732625261
  • 2017年01月02日 16:05
  • 460

asp.net服务器控件与html服务器控件的区别

在ASP.NET开发中用到的控件可以分为三种:传统html控件(比如)、html服务器控件(比如)以及ASP.NET服务器控件(比如)。 初学ASP.NET,第一种控件相当于在客户端运行,在服务...
  • judyge
  • judyge
  • 2016年01月09日 22:44
  • 231

为服务器控件加入客户端事件处理的几种方法

服务器端的处理虽然方便,但因为每次都要PostBack,因而效率不高,很多时候需要为服务器端控件写入客户端事件处理。把各种方法总结一下:    1)在HTML代码的标签中直接写。如下        o...
  • huis
  • huis
  • 2005年08月31日 16:13
  • 1115
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:FileUpload 服务器控件示例
举报原因:
原因补充:

(最多只允许输入30个字)