it-source

다운로드 기능이 asp.net 업데이트 패널 내에서 작동하지 않음

criticalcode 2023. 2. 16. 21:47
반응형

다운로드 기능이 asp.net 업데이트 패널 내에서 작동하지 않음

다음을 포함하는 웹 사용자 컨트롤이 있습니다.FormView폼뷰에는 구직자의 상세 정보가 표시됩니다.관리자/HR이 이력서를 다운로드할 수 있도록 "Download Resume" 링크 버튼을 제공했습니다.UpdatePanel이 포함된 aspx 페이지에 이 컨트롤을 배치했습니다.Download Link(링크 다운로드)를 제외한 모든 것이 정상적으로 동작합니다.

명령어 on donwload 링크버튼을 지정했습니다.다운로드 시작 명령어와 관련된 기능이 있습니다.

다음은 제가 구현한 코드입니다.

//Command on 'Download' link button within FormView
protected void lnkDownload_Command(object sender, CommandEventArgs e)
{
    if (e.CommandName.Equals("Download"))
    {
        StartDownload(e.CommandArgument.ToString());
    }
}

//My routine to download document
//sFileInfo contains filepath$==$mimetype
protected void StartDownload(string sFileInfo)
{
    string[] d = sFileInfo.ToString().Split((new string[] { "$==$" }), StringSplitOptions.None);
    string filename = d[0];
    string docType = d[1];

    System.IO.FileInfo file = new System.IO.FileInfo(d[0]);

    if (file.Exists)
    {
        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=" + d[0]);
        Response.AddHeader("Content-Length", file.Length.ToString());
        Response.ContentType = d[1];
        Response.WriteFile(file.FullName);
        Response.End();
    }
    else
    {
        Server.Transfer("~/Mesgbox.aspx?cat=2");
    }
}

업데이트 패널을 분리하면 코드는 정상적으로 동작하지만 업데이트 패널을 사용하면 스크립트 오류가 발생합니다.

제안...?

시간을 내주셔서 감사합니다.

전체 페이지 포스트백을 시작하려면 업데이트 패널에 포스트백 트리거를 추가합니다.

<asp:UpdatePanel runat="server">
    <Triggers>
        <asp:PostBackTrigger ControlID="YourControlID" />
    </Triggers>
    <ContentTemplate>
        .....

결과는 ScriptManager에 의해 DIV(응답 전체가 아님) 업데이트에 사용되므로 UpdatePanel 부분 포스트백으로 첨부 파일을 반환할 수 없습니다.가장 간단한 수정은 다운로드 버튼을 포스트백 컨트롤로 만드는 것입니다.그러면 그 버튼이 풀 포스트백을 시작합니다.Page_Load에 포함할 코드는 다음과 같습니다.

ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(this.lnkDownload);

업데이트 패널 내부에서 문서를 다운로드할 수 있습니다.

업데이트 패널이 있고 내부에는 네스트된 리피터가 3개 있습니다.가장 내부 리피터에서는 LinkButtons를 사용하여 일련의 다운로드 링크를 구축합니다.각 링크에는 웹 서비스를 통해 문서를 가져오고 디스패치하는 명령이 포함되어 있습니다.

각 리피터에는 OnItemDataBound 메서드가 있습니다.마지막 리피터에는 다음과 같은 것이 있습니다.

        protected void LinkDocRepeaterOnItemDataBound(object sender, RepeaterItemEventArgs e) {
            if(!(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)) {
            return;
                }
            LinkButton linkButton = (LinkButton)e.Item.FindControlRecursive("LinkId");
            var scriptManager = ScriptManager.GetCurrent(this.Page);
            if (scriptManager != null) {
               scriptManager.RegisterPostBackControl(linkButton);
            }
        }

각 링크 버튼이 문서를 다운로드합니다.

내 상황:

sql데이터에서 장시간 실행중인 엑셀파일을 로드하여 파일 작성 중에 spinner gif를 표시하도록 업데이트 진행패널에서 파일을 다운로드하고 싶었습니다.내가 생각했던 것보다 더 까다로웠어.

이 링크는 검색에서 높은 위치를 차지했고, 그것을 피하려고 노력한 결과 iframe이 나에게 유용하다는 것을 알게 되었다.

iframe 비동기 다운로드

결국 이렇게 된 거야(이 코드는 테스트되지 않았습니다.)

MyPage.aspx...(업데이트 패널 표시, 트리거 없음)

<asp:Button runat="server" ID="btnExcelExport" Text="Export to Excel" OnClick="btnExcelExport_Click" />

<iframe runat="server" id="ifmExcel" width="0" height="0" marginheight="0" marginwidth="0"
                    frameborder="0" />

MyPage.aspx.cs

        protected void btnExcelExport_Click(object sender, EventArgs e)
        {
            //long running process here, taking advantage of the update progress panel
            var bytes = GetExcelFile();
            //generate a key to pass to the download page to access the file bytes
            var cacheKey = Guid.NewGuid().ToString("N");//N means no hyphens
            //placing the result in cache for a few seconds so the download page can grab it             
            Context.Cache.Insert(key: cacheKey, value: bytes, dependencies: null, absoluteExpiration: DateTime.Now.AddSeconds(30), slidingExpiration: System.Web.Caching.Cache.NoSlidingExpiration);
            ifmExcel.Attributes.Add("src", String.Format("MyDownloadPage.aspx?cacheKey={0}", cacheKey));
        }

MyDownloadPage.aspx.cs...

        protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            var bytes = Context.Cache.Get(Request.QueryString.Get("cacheKey")) as byte[];
            Response.Clear();
            Response.AddHeader(
                "content-disposition", string.Format("attachment; filename={0}.xlsx", "Invoice"));
            Response.ContentType = "application/xlsx";
            Response.BinaryWrite(bytes);
            Response.End();
        }
    }

다른 비동기 포스트백과 마찬가지로 정상적으로 동작합니다.

ASPX 마크업:

 <asp:UpdatePanel ID="UpdatePanel5" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:GridView ID="gv_Files" runat="server" AllowPaging="True" PageSize="7" OnPageIndexChanging="gv_Files_PageIndexChanging" AutoGenerateColumns="false" EmptyDataText="No files uploaded" GridLines="None">
            <Columns>
                <asp:BoundField DataField="Filename" HeaderText="File Name"  ItemStyle-CssClass="Files_css"  />
                <asp:BoundField DataField="DateCreated" HeaderText="Upload Date" ItemStyle-CssClass="Files_css"  />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:LinkButton ID="lnkDownload" Text="Download" CausesValidation="false" CommandArgument='<%# Eval("FileName_Guid")+  ";" + Eval("Filename")  %>' runat="server" OnClick="DownloadFile"></asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:LinkButton ID="lnkDelete" Text="Del" CausesValidation="false" CommandArgument='<%# Eval("FileName_Guid")+ ";" + Eval("File_ID")+ ";" + Eval("Filename") + ";" + Eval("Platform_Config_ID") %>' runat="server" OnClick="DeleteFile" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </ContentTemplate>
    <Triggers>
        <%--<asp:AsyncPostBackTrigger ControlID="gv_Files" />--%>                   
    </Triggers>
</asp:UpdatePanel>

코드 배면:

    protected void UploadFile(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile)
        {
            string FileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
            string extension = "." + FileName.Split('.')[1].ToString();
            string FileName_Guid = Convert.ToString(Guid.NewGuid()) + extension;
            FileUpload1.PostedFile.SaveAs(@"C:\Uploads\" + FileName_Guid);
            string Platform_Config_ID = PlatformConfigID.Value;
            DataTable dt = new DataTable();
            dt = DAL.Upload_File(FileName_Guid, FileName, Platform_Config_ID);

            gv_Files.DataSource = dt;
            gv_Files.DataBind();
            ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
            scriptManager.RegisterPostBackControl(gv_Files);
        }
    }

    protected void DownloadFile(object sender, EventArgs e)
    {
        try
        {                
            LinkButton lnkDownload = (LinkButton)sender;
            GridViewRow row = (GridViewRow)lnkDownload.NamingContainer;
            LinkButton download = row.FindControl("lnkDownload") as LinkButton;
            ScriptManager.GetCurrent(this).RegisterPostBackControl(download);
            string FileName = (sender as LinkButton).CommandArgument.Split(';')[0].ToString();
            string OriginalFileName = (sender as LinkButton).CommandArgument.Split(';')[1].ToString();
            string FilePath = @"C:\Uploads\" + FileName.ToString();
            FileInfo file = new FileInfo(FilePath);
            if (file.Exists)
            {                    
                Response.ContentType = ContentType;
                Response.AppendHeader("Content-Disposition", "attachment; filename=" + OriginalFileName);
                Response.Headers.Set("Cache-Control", "private, max-age=0");
                Response.WriteFile(FilePath);                    
                Response.End();                                     
            }                
        }
        catch (Exception ex)
        {
            // do nothing
        }
    }


    protected void DeleteFile(object sender, EventArgs e)
    {
        string FileName_Guid = (sender as LinkButton).CommandArgument.Split(';')[0].ToString();
        string File_ID = (sender as LinkButton).CommandArgument.Split(';')[1].ToString();
        string Filename = (sender as LinkButton).CommandArgument.Split(';')[2].ToString();
        string Platform_Config_ID = (sender as LinkButton).CommandArgument.Split(';')[3].ToString();
        string FilePath = @"C:\Uploads\" + FileName_Guid;
        File.Delete(FilePath);

        DataTable dt = new DataTable();
        dt = DAL.Delete_File(File_ID, Filename, Platform_Config_ID);

        gv_Files.DataSource = dt;
        gv_Files.DataBind();
    }

업데이트 패널에서 응답 개체를 사용할 수 없습니다.

다음의 순서를 시험해 주세요.

  1.  

    <asp:UpdatePanel ID="UpdatePanel5" runat="server" l**UpdateMode="Conditional"**>
    <asp:GridView ID="gv_Files" runat="server" AllowPaging="True" PageSize="7" OnPageIndexChanging="gv_Files_PageIndexChanging" AutoGenerateColumns="false" EmptyDataText="No files uploaded" GridLines="None">
    
  2. 이면) ('코드 이면)UploadFile()

    ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
    scriptManager.RegisterPostBackControl(gv_Files);
    
  3. DownloadFile()

    DownloadFile() --> LinkButton download = row.FindControl("lnkDownload") as LinkButton;
    ScriptManager.GetCurrent(this).RegisterPostBackControl(download);
    

언급URL : https://stackoverflow.com/questions/5461525/download-feature-not-working-within-update-panel-in-asp-net

반응형