簡體   English   中英

如何在ASP .NET C#中使用GridView上載和下載多個文件而無需頁面刷新?

[英]How to upload and download multiple files without Page Refresh using a GridView in ASP .NET C#?

我正在一個項目上工作一個星期,該項目具有上載和下載pdf和jpg文件的功能,該項目來自一個朋友,但由於他出差而被分配給我。

關鍵是,這種上傳和下載文件的功能非常有趣,我進行了幾處更改,這使我在下載文件時遇到了嚴重問題。

最初,我們有一個Web表單(ASPX),它是MasterPage的一部分,在此表單的一部分中,實現了ASCX控件,該控件是具有所有文件加載和卸載的控件,在此控件中有一個按鈕添加一個文件加載器(HyperLink),另一個下載(帶有標志runat =“ server”的按鈕),最后一部分是GridView,代碼如下:

<%@ Control Language="C#" CodeBehind="MultiUpload.ascx.cs" Inherits="D_Soft.DynamicData.FieldTemplates.MultiUpload" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" Tagprefix="cc1" %>

<fieldset class="fUploadControl">
    <legend>
        <h1>Upload Files</h1>
    </legend>
    <asp:UpdatePanel ID="upMultiUpload" runat="server" UpdateMode="Always">
        <ContentTemplate>

            <asp:Panel ID="pnlUpload" runat="server">

                <asp:FileUpload ID="upldFile_0" CssClass="form-control" runat="server" />

            </asp:Panel>
            <br />

            <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-2 col-lg-2">
                <asp:HyperLink ID="lnkAddFileUpload" CssClass="btn btn-block btn-primary" NavigateUrl="javascript:addFileUploadCtrl();" runat="server"><i class="fa fa-plus"></i>&nbsp;&nbsp;Add</asp:HyperLink>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-2 col-lg-2">
                <button runat="server" id="btnUpload" data-ajax="false" type="button" onserverclick="btnUpload_Click" class="btn btn-block btn-primary"><i class="fa fa-upload"></i>&nbsp;&nbsp;Upload</button>
            </div>

        </div>
        </ContentTemplate>
        <Triggers>
            <asp:PostBackTrigger ControlID="btnUpload" />
        </Triggers>
    </asp:UpdatePanel>

    <br />

    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
            <div style="width: 100%; overflow: auto">
                    <asp:GridView ID="GridFiles" runat="server"
                        AutoGenerateColumns="False" CellPadding="3" DataKeyNames="RowId,File,Path,Exists"
                        Font-Names="Calibri" Font-Size="10pt" OnRowDeleting="GridFilesArchivos_RowDeleting" OnSelectedIndexChanged="GridFiles_SelectedIndexChanged"
                        ForeColor="#333333" GridLines="Both" Height="25px"
                        Width="500px"
                        Style="font-size: 10pt"
                        CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt">
                        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                        <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
                        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
                        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                        <Columns>
                            <asp:BoundField DataField="RowId" SortExpression="RowId" Visible="False" />
                            <asp:BoundField DataField="File" HeaderText="FILE" SortExpression="File">
                                <HeaderStyle HorizontalAlign="Center" />
                                <ItemStyle Width="85%" HorizontalAlign="Center" />
                            </asp:BoundField>
                            <asp:BoundField DataField="Path" SortExpression="Path" Visible="False" />
                            <asp:BoundField DataField="Exists" SortExpression="Exists" Visible="False" />
                            <asp:CommandField ItemStyle-Width="15%" ItemStyle-HorizontalAlign="Center" ShowCancelButton="false" HeaderText="ACTION" ButtonType="Image" Visible="true" DeleteImageUrl="~/img/trash.png" ShowDeleteButton="True" ShowSelectButton="true" SelectImageUrl="~/img/download.png" />
                        </Columns>
                    </asp:GridView>
            </div>
        </div>
    </div>
</fieldset>

GUI如下所示:

在此處輸入圖片說明

對於代碼C#,它具有文件上傳和文件下載事件,但是,由於某些Web表單控件適用於回發調用,因此我不得不進行更改,並且我不希望頁面再次加載,您會看到類似以下內容:

protected void Page_Load(object sender, EventArgs e)
{
    Page.Form.Attributes.Add("enctype", "multipart/form-data");
}

protected void btnUpload_Click(object sender, EventArgs e)
{
    UploadFiles();
}

public bool UploadFiles()
{
    DataTable dtFiles = new DataTable();

    dtFiles.Columns.Add(new DataColumn("RowId", typeof(int)));
    dtFiles.Columns.Add(new DataColumn("File", typeof(string)));
    dtFiles.Columns.Add(new DataColumn("Path", typeof(string)));
    dtFiles.Columns.Add(new DataColumn("Exists", typeof(string)));

    //Number of files, here the files to be uploaded are captured, 
    //before uploading any file valid the size, name and extension of the 
    //file, this code I have omitted because I do not think it is necessary

    HttpFileCollection col = Request.Files;

    int cantFiles = 0;

    //This code allows me to save each of the files in Request.Files

    for (int i = 0; i < fcol.Count; i++)
    {
        HttpPostedFile postedF = col[i];
        if (postedF.ContentLength > 0)
        {
            string tmpsave = string.Format("{0}\\{1}", dirPath, Path.GetFileName(postedF.FileName));

            //Create a temporary file name that will be used for checking duplicates

            string tempfileName = "";

            // Check if there is already a file with the same name to load

            if (System.IO.File.Exists(tmpsave))
            {
                int counter = 2;
                while (System.IO.File.Exists(tmpsave))
                {
                    tempfileName = counter.ToString() +"_"+ Path.GetFileName(postedF.FileName);
                    tmpsave= string.Format("{0}\\{1}", dirPath, tempfileName);
                    counter++;
                }
            }

            //Save File in server

            postedF.SaveAs(tmpsave);

            //Update Rows

            DataRow dwRow = dtFiles.NewRow();

            dwRow["RowId"] = cantFiles;
            dwRow["File"] = Path.GetFileName(postedF.FileName);
            dwRow["Path"] = tmpsave;
            dwRow["Exists"] = "NO";

            dtFiles.Rows.Add(dwRow);

            cantFiles++;
        }
    }

    //Update GridView

    GridFiles.DataSource = dtFiles;
    GridFiles.DataBind();
}

protected void GridArchivos_SelectedIndexChanged(object sender, EventArgs e)
{
    string stPathDes = this.GridFiles.DataKeys[this.GridFiles.SelectedIndex][2].ToString();

    DownloadFile(HttpContext.Current, stPathDes, Path.GetFileNameWithoutExtension(stPathDes) + Path.GetExtension(stPathDes).ToLower());
}

public static void DownloadFile(System.Web.HttpContext context, string stUbication, string stName)
{

    stUbication can be: "D:\\Project\\ProjectUpload\\ProjectUpload.Web\\Files\\anyfolder\\\\123.pdf"

    stName can be: "123.pdf"

    try
    {
        System.IO.FileInfo toDownload = new System.IO.FileInfo(stUbication);
        System.Web.HttpResponse response = context.Response;

        if (toDownload.Exists)
        {
            response.ClearContent();
            response.Clear();
            response.AddHeader("Content-Disposition", "attachment; filename=" + stName);
            response.AddHeader("Content-Length", toDownload.Length.ToString());
            response.ContentType = "application/octet-stream";
            response.WriteFile(stUbication);
            response.Flush();
            //response.End();
            context.ApplicationInstance.CompleteRequest();
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Page_Load方法的第一行以及UpdatePanel和PostBackTrigger的實現允許我加載多個文件,這是因為Request.File變量始終為空。

現在,文件上傳可以正常工作了。 行response.End(); 之所以被注釋,是因為我生成了一個類型為“由於代碼已優化或本機框架位於調用堆棧頂部而無法評估表達式”的異常。

問題在於,從不下載用於下載文件的按鈕,並且不會觸發進度條,此外,JavaScript控制台中還會發生錯誤(“無法讀取未定義的屬性'PRM_ParserErrorDetails'”):

在此處輸入圖片說明

該錯誤沒有太多的文檔,我真的不知道我是在錯誤地構建代碼還是需要實現其他東西。

此控件以Web表單(ASPX)的形式實現,如下所示:

<%@ Page Title="" Language="C#" MasterPageFile="~/TheMaster.Master" AutoEventWireup="true" CodeBehind="MyForm.aspx.cs" Inherits="ProjectUpload.Web.MyForm" MaintainScrollPositionOnPostback="true" %>
<%@ Register Src="~/Controls/MultiUpload.ascx" TagPrefix="uc1" TagName="MultiUpload" %>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">

    <asp:UpdatePanel ID="upPanelRequest" runat="server">
        <ContentTemplate>

            //In this UpdatePanel I have a button (btnButtonSave)
            //I do this to not refresh the page again, this button performs a process with the database, 
            //therefore, it is delayed and I need to do the Return to show a progress bar (gif)

            <uc1:MultiUpload runat="server" id="MultiUpload" />

            <button runat="server" type="button" id="btnButtonSave" onclick="DisableButton(this);" onserverclick="btnButtonSave_ServerClick" class="btn btn-success btn-block">
                <i class="fa fa-save"></i>&nbsp;&nbsp;SAVE
            </button>

        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="btnButtonSave" /> 
            <asp:AsyncPostBackTrigger ControlID="MultiUpload" /> 
        </Triggers>
    </asp:UpdatePanel>

</asp:Content>

我注意到的一件奇怪的事是,當我上傳文件時,表單會完全重新加載。 我可能用錯了什么?

有誰能夠幫助我?

我找到了一個解決方案,它非常簡單,只需要將GridView放在UpdatePanel中,然后指向該控件中的PostBackTrigger:

<asp:UpdatePanel ID="upMultiUpload" runat="server" UpdateMode="Always">
    <ContentTemplate>

        <asp:GridView ID="GridFiles" runat="server"> ... </asp:GridView>

    </ContentTemplate>
    <Triggers>

        <asp:PostBackTrigger ControlID="btnUpload" />
        <asp:PostBackTrigger ControlID="GridFiles" />

    </Triggers>
</asp:UpdatePanel>

JavaScript的問題由此消失了,但是有必要修改代碼以撤消文件:

response.ClearContent();
response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename=" + stName);
response.AddHeader("Content-Length", toDownload.Length.ToString());
response.ContentType = "application/octet-stream";
response.WriteFile(stUbication);
response.Flush();

但是,如果沒有回發,它將無法工作,因為必須重新加載頁面才能發送文件,我在Internet上發現的某些實現是使用AsyncFileUpload控件實現的,但由於我負責多個文件,因此它不適用於我的項目其他實現,它們使用AJAX和ASHX,但就我而言,我需要GridView ...我仍然不知道是否有解決此問題的方法。

這些鏈接對於了解該問題很有幫助:

文件上傳不適用於ASP.Net中的AsyncPostBackTrigger

https://forums.asp.net/t/1669892.aspx?Request+Files+is+empty

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM