65.9K
CodeProject 正在变化。 阅读更多。
Home

多文件上传用户控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (81投票s)

2008 年 3 月 11 日

CPOL

5分钟阅读

viewsIcon

422253

downloadIcon

11407

本文介绍了如何创建一个带有事件和属性的文件上传用户控件。

MultifileUploadUserControl.gif

引言

我们知道,input文件元素一次只允许选择一个文件,也就是说,您一次只能使用一个input文件元素上传一个文件。如果您想一次上传多个文件,那么您必须添加与您想要上传的文件数量相同的input文件元素。原因在于您只能将文件上传信息存储在一个input文件元素中。由于安全原因,您无法通过编程方式直接为input文件元素设置值。

现在,我将在此展示一个ASP.NET 用户控件,它可以用于一次上传多个文件。我将其命名为“多文件上传用户控件”。这并不意味着此用户控件可以使用单个文件input元素上传多个文件。实际上,在此控件中,input文件元素在选择文件后会隐藏,并在此位置添加一个新的文件input元素。由于此现象发生得非常快,所以看起来只有一个文件input元素。隐藏选定的文件input元素并创建一个新的文件input元素是通过JavaScript完成的。

用户控件的外观

此用户控件由一个input文件元素、一个ListBox和三个Button组成。以下是它们的简要说明:

Description1.png

  • 输入文件元素:用于选择文件。
  • ListBox:用于显示选定的文件。
  • 添加按钮:用于将选定的文件添加到ListBox中。
  • 清除按钮:用于从ListBox中删除所有选定的文件。
  • 上传按钮:用于将所有选定的文件上传到服务器。
  • 删除链接:此链接出现在每个选定文件的右侧。点击它可以从选定文件列表中删除该文件。

用户控件的属性

此用户控件有两个公共属性。

  • Rows:用于设置/获取要显示的可见行数。默认值为6。
  • UpperLimit:用于设置/获取最大上传文件数。

用户控件的事件

此用户控件只有一个服务器端事件。

  • Click:当点击上传按钮时触发。表示MultipleFileUpload控件Click事件签名的委托如下所示:
public delegate void MultipleFileUploadClick(object sender, FileCollectionEventArgs e)

我稍后会讨论它。第二个参数是FileCollectionEventArgs类,它提供了关于已发布文件的有用信息。此类具有以下只读公共属性:

  • PostedFiles:返回所有已发布文件的HttpFileCollection
  • Count:返回已发布文件的总数。
  • HasFiles:获取一个值,指示此用户控件是否包含任何已发布文件。
  • TotalSize:返回所有已发布文件的总大小(KB)。

使用用户控件

将用户控件拖放到ASPX页面中,并为RowsUpperLimit属性设置值。此用户控件的HTML代码如下所示:

<uc1:MultipleFileUpload ID="MultipleFileUpload1" runat="server" UpperLimit="4" Rows="6" />

接下来,为此用户控件的Click事件创建一个事件处理程序:

protected void MultipleFileUpload1_Click(object sender, FileCollectionEventArgs e)
{
   ...
}

现在,通过在事件名称前添加前缀On来将事件处理程序连接到控件标签。现在,HTML代码将如下所示:

<uc1:MultipleFileUpload ID="MultipleFileUpload1" OnClick="MultipleFileUpload1_Click"
                        runat="server" UpperLimit="4" Rows="6" />

使用用户控件上传已发布的文件

最后,选择所需文件并点击用户控件的上传按钮以上传已发布的文件。上传已发布文件的代码如下:

protected void MultipleFileUpload1_Click(object sender, FileCollectionEventArgs e)
{
   HttpFileCollection oHttpFileCollection = e.PostedFiles;
   HttpPostedFile oHttpPostedFile = null;
   if (e.HasFiles)
   {
      for (int n = 0; n < e.Count; n++)
      {
         oHttpPostedFile = oHttpFileCollection[n];
         if (oHttpPostedFile.ContentLength <= 0)
            continue;
         else
            oHttpPostedFile.SaveAs(Server.MapPath("Files") + "\\" + 
               System.IO.Path.GetFileName(oHttpPostedFile.FileName));
      }
   }
}

上面的代码简单明了,不言自明。

用户控件HTML

此用户控件的HTML非常简单。

<asp:Panel ID="pnlParent" runat="server" Width="300px" 
           BorderColor="Black" BorderWidth="1px" BorderStyle="Solid">
   <asp:Panel ID="pnlFiles" runat="server" Width="300px" HorizontalAlign="Left">
      <asp:FileUpload ID="IpFile" runat="server" />
   </asp:Panel>
   <asp:Panel ID="pnlListBox" runat="server" Width="292px" BorderStyle="Inset">
   </asp:Panel>
   <asp:Panel ID="pnlButton" runat="server" Width="300px" HorizontalAlign="Right">
      <input id="btnAdd" onclick="javascript:Add();" 
             style="width: 60px" type="button" runat="server" value="Add"/>
      <input id="btnClear" onclick="javascript:Clear();" 
             style="width: 60px" type="button" value="Clear" runat="server"/>
      <asp:Button ID="btnUpload" OnClientClick="javascript:return DisableTop();" 
           runat="server" Text="Upload" Width="60px" OnClick="btnUpload_Click"/>
      <br />
      <asp:Label ID="lblCaption" runat="server" Font-Bold="True" 
           Font-Names="Verdana" Font-Size="XX-Small" ForeColor="Gray">
      </asp:Label> 
   </asp:Panel>
</asp:Panel>

此用户控件中有三个Panel。文件面板 [ID="pnlFiles"] 用于input文件元素,ListBox面板 [ID="pnlListBox"] 用于列出选定的文件,按钮面板 [ID="pnlButton"] 有三个按钮:两个用于客户端事件,一个用于服务器端。添加按钮 [id="btnAdd"] 和清除按钮 [id="btnClear"] 都有客户端onclick事件。服务器端按钮 [ID="btnUpload"] 既有客户端OnClientClick事件,也有服务器端OnClick事件。Label [ID="lblCaption"] 在这里用于显示此用户控件的上限。

我在文件面板中使用了ASP.NET 2.0的FileUpload控件 [ID="IpFile"],而不是使用input文件元素。原因是它会自动将enctype="multipart/form-data"添加到页面的<form>元素中。

用户控件代码

用户控件类的Click事件定义如下。

public event MultipleFileUploadClick Click;

表示Click事件签名的委托如下所示:

public delegate void MultipleFileUploadClick(object sender, FileCollectionEventArgs e);

FileCollectionEventArgs是一个事件参数类,其中包含有关已发布文件的基本信息。我稍后会讨论它。此用户控件的Click事件在上传按钮的click事件中触发。

protected void btnUpload_Click(object sender, EventArgs e)
{
   // Fire the event.
   Click(this, new FileCollectionEventArgs(this.Request));
}

用户控件类有一个私有方法GetJavaScript()。此方法为该用户控件生成必要的客户端JavaScript。它在用户控件的Page_Load事件中使用RegisterStartupScript方法注册。

现在,让我们讨论表示Click事件第二个参数的FileCollectionEventArgs类。

public class FileCollectionEventArgs : EventArgs
{
    private HttpRequest _HttpRequest;
    public HttpFileCollection PostedFiles
    {
        get
        {
            return _HttpRequest.Files;
        }
    }
    public int Count
    {
        get { return _HttpRequest.Files.Count; }
    }
    public bool HasFiles
    {
        get { return _HttpRequest.Files.Count > 0 ? true : false; }
    }
    public double TotalSize
    {
        get
        {
            double Size = 0D;
            for (int n = 0; n < _HttpRequest.Files.Count; ++n)
            {
                if (_HttpRequest.Files[n].ContentLength < 0)
                    continue;
                else
                    Size += _HttpRequest.Files[n].ContentLength;
            }
            return Math.Round(Size / 1024D, 2);
        }
    }
    public FileCollectionEventArgs(HttpRequest oHttpRequest)
    {
        _HttpRequest = oHttpRequest;
    }
}

FileCollectionEventArgs类派生自EventArgs基类。FileCollectionEventArgs类的构造函数接受一个HttpRequest对象作为参数。FileCollectionEventArgs类具有前面讨论的四个公共属性。HttpRequest类的files属性将所有已发布的文件作为HttpFileCollection类。其余属性很容易理解。

限制

使用此用户控件上传到服务器的最大大小约为4MB,即,所有要上传的文件大小之和应小于4MB。您不能上传任何大于4MB的文件。如果您想上传超过4MB的文件,则必须更改web.config文件;例如,如果您想上传大约10MB,则需要在web.config文件的system.web部分的<httpRuntime>节点中进行以下更改。

<httpRuntime maxRequestLength="102400" executionTimeout="275"/> 

您可以在MSDN网站上找到更多相关信息 [^]

结论

我已尽力使此用户控件代码无错误。我非常欢迎对此用户控件的进一步改进提出建议。我已在各种浏览器上测试过此用户控件,并且它运行良好。下面列出了浏览器及其版本:

Browsers.png

© . All rights reserved.