您的位置:首页 > 编程语言 > ASP

在ASP.NET中利用SlickUpload来上传大文件

2010-07-26 09:29 435 查看
SlickUpload的介绍
最近在看《ASP.NET MVC2 IN ACTION》英文版时发现里面介绍到一个在ASP.NET中上传大文件的ASP.NET控件,叫SlickUpload,软件的介绍下载和介绍网址是:http://krystalware.com/Products/SlickUpload/
我们知道,在ASP.NET中对于上传文件可以利用FileUpload控件或者<input type="file" name="file"/>这样的方式就可以上传,但是利用这样的方式上传存在一些缺点,比如默认一次只能上传一个文件及上传的文件的大小也有限制,除此之外,利用这种方式上传不能以直观的方式显示上传的进度情况,于是有了各种各样的第三方解决方案,比如SWFUpload等。不过因为在最近的版本中ADOBE公司增强了权限控制,所以SWFUpload也有些不太灵光了,这里介绍另外一种文件上传控件SlickUpload。SlickUpload是一款共享软件,它的购买地址是http://krystalware.com/purchase/,如果公司有经常上传超大文件需求的,不妨购买。
SlickUpload的原理如下图:




可以看出它的处理流程如下:
对于请求中的每个文件SlickUpload都会调用定义好的上传文件流供应者来写文件数据,SlickUpload支持两种内置的文件处理方式和用户自定义的处理方式:
文件系统,即将文件保存到服务器文件下;
SQL,即将文件保存到SQL服务器中;
根据用户逻辑的自定义方式;
SlickUpload可以在ASP.NET WebForm和ASP.NET MVC及ASP.NET AJAX项目中运行,可以以带进度显示上传超过上G的文件。
在不同环境下最大可支持上传的文件大小:
IIS 5:最大可支持上传2 GB
IIS 6:最大支持上传4 GB
IIS 7传统模式:最大支持上传4 GB
IIS 7 集成模式:最大支持上传2 GB
VS.NET集成WebDev server环境下:最大支持2 GB
当然上面的最大支持需要在web.config文件中的<httpRuntime>节点的maxRequestLength属性。



SlickUpload的安装
1.程序集的安装
首先请将Krystalware.SlickUpload.dll拷贝到Web项目的bin目录下,这个程序集包含了SlickUpload的HttpModule模块。
2.添加SlickUpload控件到VS的控件工具箱(周公的VS版本为VS2008SP1)
步骤如下:
2.1用VS打开Web项目或者包含Web项目的解决方案。
2.2在VS上的控件箱空白处鼠标右键点击,选择“选择项”,出现如下图所示的界面:



2.3在打开的对话框中选择“浏览”,如下图所示:



找到Krystalware.SlickUpload.dll所在的位置,然后点击确定,这样就完成了将SlickUpload添加到控件箱。如下图所示:



3.在web.config中配置
3.1配置configSections节点
打开web.config文件找到configSections节点(如果没有的话请在<configuration>元素下添加),在configSections节点下添加如下内容:

<sectionGroup name="slickUpload"> 
    <section name="uploadParser" type="Krystalware.SlickUpload.Configuration.NameValueConfigurationSectionHandler, Krystalware.SlickUpload" /> 
    <section name="uploadStreamProvider" type="Krystalware.SlickUpload.Configuration.NameValueConfigurationSectionHandler, Krystalware.SlickUpload" /> 
    <section name="statusManager" type="Krystalware.SlickUpload.Configuration.StatusManagerConfigurationSectionHandler, Krystalware.SlickUpload" /> 
</sectionGroup>


添加slickUpload节点

在<configuration>元素下添加slickUpload节点,如下:

<slickUpload> 
    <uploadStreamProvider location="~/Files" existingAction="Overwrite" /> 
</slickUpload>


其中的location表示文件上传后的存放位置,existingAction表示如果在服务端已经存在同名文件如何处理。
system.web/httpModules节点配置
在system.web节点下添加如下内容:

<httpModules> 
    <add name="HttpUploadModule" type="Krystalware.SlickUpload.HttpUploadModule, Krystalware.SlickUpload" /> 
</httpModules>


如果在web.config中已经存在system.web/httpModules节点,则只需将<add ..../>部分添加到这个节点下即可。
system.web/httpHandlers节点配置
在system.web节点下添加如下内容:

<httpHandlers> 
    <add path="SlickUpload.axd" verb="GET,POST" type="Krystalware.SlickUpload.SlickUploadHandler, Krystalware.SlickUpload" /> 
</httpHandlers>


如果在web.config中已经存在system.web/httpModules节点,则只需将<add ..../>部分添加到这个节点下即可。
system.web/httpRuntime节点配置
在system.web节点下添加如下内容:

<httpRuntime  maxRequestLength="1024000"  executionTimeout="600" />


以上配置表示允许最大上传1GB的文件(maxRequestLength的单位为MB),程序执行超时时间为10分钟(executionTimeout的单位为秒)。
经过如下配置之后就可以在我们的ASP.NET项目中使用SlickUpload项目了。

SlickUpload的使用

快速上手指南
下面是一个简单使用的例子,代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SlickUploadQuickStart.aspx.cs" Inherits="SlickUploadQuickStart" %>

<%@ Register assembly="Krystalware.SlickUpload" namespace="Krystalware.SlickUpload.Controls" tagprefix="kw" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>SlickUpload Quick Start</title>
    <mce:script type="text/javascript"><!--
    function cancelUpload() {
        kw.get("<%=SlickUpload1.ClientID %>").cancel();
    }     
// --></mce:script>
</head>
<body>
    <h1>SlickUpload Quick Start</h1>
    <form id="form1" runat="server">
        
    <kw:SlickUpload ID="SlickUpload1" runat="server" ShowDuringUploadElements="cancelButton" 
        onuploadcomplete="SlickUpload1_UploadComplete" Width="480px">
        <downlevelselectortemplate>
            <input type="file" />
        </downlevelselectortemplate>
        <uplevelselectortemplate>
            <input type="button" value="选择文件" />
        </uplevelselectortemplate>
        <filetemplate>
            <kw:FileListRemoveLink runat="server">
                [x] 删除</kw:FileListRemoveLink>
            <kw:FileListFileName runat="server" />
            <kw:FileListValidationMessage runat="server" ForeColor="Red" />
        </filetemplate>
        <progresstemplate>
            <table width="100%">
                <tr>
                    <td>
                        文件上传中
                        <kw:UploadProgressElement runat="server" Element="FileCountText">
                        </kw:UploadProgressElement>
                        ,
                        <kw:UploadProgressElement runat="server" Element="ContentLengthText">
                            (calculating)</kw:UploadProgressElement>
                        .
                    </td>
                </tr>
                <tr>
                    <td>
                        当前正在上传:
                        <kw:UploadProgressElement runat="server" Element="CurrentFileName">
                        </kw:UploadProgressElement>
                        , 进度
                        <kw:UploadProgressElement runat="server" Element="CurrentFileIndex">
                             </kw:UploadProgressElement>
                        /
                        <kw:UploadProgressElement runat="server" Element="FileCount">
                        </kw:UploadProgressElement>
                        .
                    </td>
                </tr>
                <tr>
                    <td>
                        上传速度:
                        <kw:UploadProgressElement runat="server" Element="SpeedText">
                            (calculating)</kw:UploadProgressElement>
                        .
                    </td>
                </tr>
                <tr>
                    <td>
                        估计剩余时间:
                        <kw:UploadProgressElement runat="server" Element="TimeRemainingText">
                            (calculating)</kw:UploadProgressElement>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div style="border:1px solid #008800;height:1.5em;position:relative">
                            <kw:UploadProgressBarElement runat="server" 
                                style="background-color:#00ee00;width:0;height:1.5em">
                            </kw:UploadProgressBarElement>
                            <div style="text-align:center;position:absolute;top:.15em;width:100%">
                                <kw:UploadProgressElement runat="server" Element="PercentCompleteText">
                                    (calculating)</kw:UploadProgressElement>
                            </div>
                        </div>
                    </td>
                </tr>
            </table>
        </progresstemplate>
    </kw:SlickUpload>
        
    <hr />
        <asp:Button ID="Button1" runat="server" Text="上传" />
         <asp:Button ID="cancelButton" runat="server" 
            onclientclick="cancelUpload();return false;" Text="Cancel" style="display:none" mce_style="display:none" />
        <br />
        <br />
        <asp:Label ID="uploadResult" runat="server"></asp:Label>
        <asp:Repeater ID="uploadFileList" runat="server" EnableViewState="False">
            <FooterTemplate></ul></FooterTemplate>
            <ItemTemplate><li><%# DataBinder.Eval(Container.DataItem, "ClientName") %></li></ItemTemplate>
            <HeaderTemplate><ul></HeaderTemplate>
        </asp:Repeater>
    </form>
</body>
</html>


后台的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Krystalware.SlickUpload;//添加引用
using Krystalware.SlickUpload.Status;//添加引用

public partial class SlickUploadQuickStart : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void SlickUpload1_UploadComplete(object sender, Krystalware.SlickUpload.Controls.UploadStatusEventArgs e)
    {
        uploadResult.Text = "上传结果: " + e.Status.State;

        if (e.Status.State == UploadState.Terminated)
            uploadResult.Text += ". 原因: " + e.Status.Reason;

        if (e.Status.State != UploadState.Terminated)
        {
            uploadFileList.DataSource = e.UploadedFiles;
            uploadFileList.DataBind();
        }
    }
}


运行这个页面会看到如下效果:



点击上传按钮会看到如下效果:



注意,如果上传的文件超过在web.config中配置的最大允许大小会上传失败,看到的界面如下:



如果上传成功,则会看到下面的界面:



在ASP.NET AJAX中使用SlickUpload
在ASP.NET项目中新建一个ASPX页面,代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SlickUploadAjax.aspx.cs" Inherits="SlickUploadAjax" %>
<%@ Register Assembly="Krystalware.SlickUpload" Namespace="Krystalware.SlickUpload.Controls"
    TagPrefix="kw" %>
<%@ Import Namespace="Krystalware.SlickUpload" %>
<%@ Import Namespace="Krystalware.SlickUpload.Status" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>SlickUpload ASP.NET AJAX Sample</title>
    <mce:script type="text/javascript"><!--
        function startUpload()
        {
            kw.get('<%=SlickUpload1.ClientID %>').submit();
        }
    
// --></mce:script>
</head>
<body>
    <h1>SlickUpload ASP.NET AJAX Sample</h1>
    <form id="Form1" runat="server">
        <asp:ScriptManager ID="ScriptManager" runat="server" EnablePartialRendering="true">
        </asp:ScriptManager>               
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <div style="border:2px dotted #ccc;padding:1em;width=500px">
                    <h2>UpdatePanel</h2>
                    <p>时间: <asp:Label ID="updateLabel" runat="server" /></p>
                    <p><asp:Button ID="updateButton" runat="server" Text="更新时间" 
                            onclick="updateButton_Click" /></p>
                    <h2>选择文件</h2>
                    <asp:Panel ID="uploadPanel" runat="server">
                        <kw:SlickUpload ID="SlickUpload1" runat="server" AutoUploadOnPostBack="false" ShowDuringUploadElements="cancelButton" HideDuringUploadElements="uploadButton" OnUploadComplete="SlickUpload1_UploadComplete">
                            <DownlevelSelectorTemplate>
                                <input type="file" />
                            </DownlevelSelectorTemplate>
                            <UplevelSelectorTemplate>
                                <input type="button" value="添加文件" />
                            </UplevelSelectorTemplate>
                            <FileTemplate>
                                <kw:FileListRemoveLink ID="FileListRemoveLink1" runat="server">
                                    [x] 删除文件</kw:FileListRemoveLink>
                                <kw:FileListFileName ID="FileListFileName1" runat="server" />
                                <kw:FileListValidationMessage ID="FileListValidationMessage1" runat="server" ForeColor="Red" />
                            </FileTemplate>
                            <ProgressTemplate>
                                <table width="100%">
                                    <tr>
                                        <td>
                                            文件上传中
                                            <kw:UploadProgressElement ID="UploadProgressElement1" runat="server" Element="FileCountText">
                                            </kw:UploadProgressElement>
                                            ,
                                            <kw:UploadProgressElement ID="UploadProgressElement2" runat="server" Element="ContentLengthText">
                                                (calculating)</kw:UploadProgressElement>
                                            .
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>
                                            当前正在上传:
                                            <kw:UploadProgressElement ID="UploadProgressElement3" runat="server" Element="CurrentFileName">
                                            </kw:UploadProgressElement>
                                            , 进度
                                            <kw:UploadProgressElement ID="UploadProgressElement4" runat="server" Element="CurrentFileIndex">
                                                 </kw:UploadProgressElement>
                                            /
                                            <kw:UploadProgressElement ID="UploadProgressElement5" runat="server" Element="FileCount">
                                            </kw:UploadProgressElement>
                                            .
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>
                                            上传速度:
                                            <kw:UploadProgressElement ID="UploadProgressElement6" runat="server" Element="SpeedText">
                                                (calculating)</kw:UploadProgressElement>
                                            .
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>
                                            预计剩余上传时间:
                                            <kw:UploadProgressElement ID="UploadProgressElement7" runat="server" Element="TimeRemainingText">
                                                (calculating)</kw:UploadProgressElement>
                                            
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>
                                            <div style="border: 1px solid #008800; height: 1.5em; position: relative">
                                                <kw:UploadProgressBarElement ID="UploadProgressBarElement1" runat="server" Style="background-color: #00ee00;
                                                    width: 0; height: 1.5em" mce_Style="background-color: #00ee00;
">
                                                </kw:UploadProgressBarElement>
                                                <div style="text-align: center; position: absolute; top: .15em; width: 100%">
                                                    <kw:UploadProgressElement ID="UploadProgressElement8" runat="server" Element="PercentCompleteText">
                                                        (calculating)</kw:UploadProgressElement>
                                                </div>
                                            </div>
                                        </td>
                                    </tr>
                                </table>
                            </ProgressTemplate>
                        </kw:SlickUpload>
                        <p>
                            <asp:Button ID="Button1" runat="server" Text="上传" OnClientClick="startUpload();return false;" />
                            <a href="javascript:kw.get('<%=SlickUpload1.ClientID %>').cancel()" id="cancelButton" style="display:none">Cancel</a>
                        </p>            
                    </asp:Panel>
                    <asp:Panel ID="resultPanel" runat="server" Visible="false">
                        <h2>上传状态</h2>
                        <% if (SlickUpload1.UploadStatus != null) { %>
                        <p>上传结果: <%=SlickUpload1.UploadStatus.State%>
                        <%if (!(SlickUpload1.UploadStatus.State == UploadState.Complete || SlickUpload1.UploadStatus.State == UploadState.PostProcessingComplete))
                          { %>
                        <br />原因: <%=SlickUpload1.UploadStatus.Reason%>
                        <% } %>
                        <br />已成功上传如下文件: <%=SlickUpload1.UploadedFiles != null ? SlickUpload1.UploadedFiles.Count.ToString() : "N/A"%></p>
                        <asp:Repeater ID="resultsRepeater" runat="server">
                            <HeaderTemplate>
                                <table class="results" width="99%" cellpadding="4" cellspacing="0">
                                    <thead>
                                        <tr>
                                            <th align="left">文件名</th>
                                            <th align="left">文件类型</th>
                                            <th align="left">文件大小(字节)</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                            </HeaderTemplate>
                            <ItemTemplate>
                                <tr>
                                    <td><%#((UploadedFile)Container.DataItem).ClientName %></td>
                                    <td><%#((UploadedFile)Container.DataItem).ContentType %></td>
                                    <td><%#((UploadedFile)Container.DataItem).ContentLength %></td>
                                </tr>
                            </ItemTemplate>
                            <FooterTemplate>
                                    </tbody>
                                </table>
                            </FooterTemplate>
                        </asp:Repeater>
                        <% } %>
                        <p><asp:Button id="newUploadButton" runat="server" Text="继续上传" 
                                onclick="newUploadButton_Click" /></p>
                    </asp:Panel>
                </div>
            </ContentTemplate>
        </asp:UpdatePanel>                    
    </form>
</body>
</html>


其对应的后台代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Krystalware.SlickUpload.Controls;

public partial class SlickUploadAjax : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void updateButton_Click(object sender, EventArgs e)
    {
        updateLabel.Text = DateTime.Now.ToLongTimeString();
    }

    protected void SlickUpload1_UploadComplete(object sender, UploadStatusEventArgs e)
    {
        uploadPanel.Visible = false;
        resultPanel.Visible = true;

        if (e.UploadedFiles != null && e.UploadedFiles.Count > 0)
        {
            resultsRepeater.DataSource = e.UploadedFiles;
            resultsRepeater.DataBind();

            resultsRepeater.Visible = true;
        }
        else
        {
            resultsRepeater.Visible = false;
        }
    }

    protected void newUploadButton_Click(object sender, EventArgs e)
    {
        uploadPanel.Visible = true;
        resultPanel.Visible = false;
    }
}


运行这个页面之后,可以看到如下界面:



上传成功之后的界面如下:



说明:在上面的两个实例中演示了如何在ASP.NET中使用SlickUpload控件来上传大文件,并且分别演示了在普通的WebForm和ASP.NET AJAX中的应用。需要注意的是这个控件的默认文字是英文的,为了演示方便我将其转换成中文了,同时也为了照顾一些对ASP.NET还不熟悉的朋友直接上手感受这个控件,我会提供本文中的示例的Demo下载(可能在我上传后需要被网站审核才能下载,通过之后我会在这里附上链接,如果看不到链接请耐心等待)。
通过上面的例子,大家应该至少可以知道如何获取SlickUpload控件上传成功之后的文件信息,那就是利用控件的OnUploadComplete事件,其事件中的UploadStatusEventArgs参数有一个UploadedFiles属性,利用这个属性我们就能获取上传的文件的信息,获取这些信息之后我们就能在程序中操作这些信息。
此外由于篇幅的原因,在本篇我暂不介绍如何SlickUpload的一些比较复杂操作和属性,比如如何在客户端对要上传的文件类型进行验证、如果让上传的文件的名称按照我们期望的格式保存等等,请大家等待下一篇。
周公
2010-07-25
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: