【问题标题】:ASP.NET download PDF feature in UpdatePanel unable to refresh UpdateProgress controlUpdatePanel 中的 ASP.NET 下载 PDF 功能无法刷新 UpdateProgress 控件
【发布时间】:2021-11-13 23:58:04
【问题描述】:

我在一个页面中有两个 UpdatePanel。第二个有 UpdateMode="Conditional" ,这里有一个链接按钮来生成 PDF 文件。 我的目标是允许 PDF 下载,同时显示等待图像(如沙漏)。 经过几天的学习,我达到了目标,但在所有操作终止后我无法隐藏图像。

在代码示例中,我简化了生成 pdf 的逻辑(在完整代码中,我使用 gridview 控件数据生成 pdf)。

  1. 如果我在 UpdatePanel 中使用异步 PostBackTrigger,即使 UpdateProgress(带有预期图像)正常工作,也不会下载 PDF。

  2. 如果我在 UpdatePanel 中使用同步 PostBackTrigger,则 PDF 会正确下载,但 updateProgress 不起作用,因为等待的图像仍保留在屏幕上。在这种情况下,我使用了客户端函数(postbackButtonClick)来显示图像。

我已经阅读了很多主题,但每个主题总是有些不同。

我的实际目标是在 PDF 制作操作完成时在客户端知道是否可以隐藏图像。

也许一般的方法是错误的?

aspx 文件

<body>
<form id="form1" runat="server">
<div>

    <asp:ScriptManager runat="server" EnableCdn="true">  </asp:ScriptManager>

    <asp:UpdateProgress ID="UpdateProgress1" DynamicLayout="true" runat="server" AssociatedUpdatePanelID="updateGrid" DisplayAfter="0" >
         <ProgressTemplate> <div class="progress"> <img src="../images/ajax-loader.gif" />&nbsp;Waiting...</div>                                                               </ProgressTemplate>
    </asp:UpdateProgress>

    <asp:UpdatePanel ID="updateGrid" runat="server">
        <ContentTemplate>
         <asp:TextBox class='form-control' ID="txtMat" runat="server" style='width:110px' Text="1672"></asp:TextBox>
         <asp:Button class='btn btn-primary' ID="cmdGO" runat="server" Text="Execute"/>
       </ContentTemplate>
    </asp:UpdatePanel>

    <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
         <ContentTemplate>
                <asp:Panel ID="panelCMD" runat="server">
                      <asp:LinkButton ID="LinkButton3" OnClientClick="return postbackButtonClick();"
                                      runat ="server" CssClass="btn btn-small btn-primary fullwidth" OnClick="mtdCreatePDF"><i class="icon icon-ok"></i>&nbsp;TEST PDF</asp:LinkButton>
                       </asp:Panel>
         </ContentTemplate>
         <Triggers >
             <asp:PostBackTrigger ControlID="LinkButton3"   />
        </Triggers>
 </asp:UpdatePanel>

     <asp:UpdateProgress ID="UpdateProgress2" ClientIDMode="Static" DynamicLayout="true" runat="server"  AssociatedUpdatePanelID="UpdatePanel2" DisplayAfter="0" >
     <ProgressTemplate>
     <div class="progress">
     <asp:image id="imgOld" runat="server" imageurl="../images/ajax-loader.gif" />
     <br />
     <img id="imgLike" src="../images/ajax-loader.gif" />&nbsp;Attendere...</div>
     </ProgressTemplate>
     </asp:UpdateProgress>


</div>
</form>
<script src="Test.js" type="text/javascript"></script>

Test.js

function postbackButtonClick() {
updateProgress = $find("UpdateProgress2");
window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
return true;

}

cs文件

 protected void mtdCreatePDF(object sender, EventArgs e)
    {

        byte[] content = null;
        string TypeOutput = "RESPONSE";
        string suffix = @"Pdf_PROD\Print.pdf";
        string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
        var stream = new MemoryStream();
        var writer = new PdfWriter(stream);
        var pdf = new PdfDocument(writer);
        var document = new Document(pdf);
        document.Add(new Paragraph("Hello world!"));
        document.Close();

        if (TypeOutput == "RESPONSE")
        {
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-disposition", "attachment;filename=print.pdf");
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            //writer.SetCloseStream(false);
            Response.BinaryWrite(stream.ToArray());
            Response.End();
        }

        else
        {
            content = stream.ToArray();
            using (FileStream fs = File.Create(nameTGT))
            {
                fs.Write(content, 0, (int)content.Length);
            }
        }


    }

【问题讨论】:

    标签: javascript c# asp.net-4.6


    【解决方案1】:

    首先,需要有一个 timeoutID 用于超时。我们稍后将使用它来禁用超时。 pdf创建完成后,会从code-behind调用hideUpdateProgress()函数来隐藏进度图。

    Test.js

    var timeoutID;
    
    function postbackButtonClick() {
    updateProgress = $find("UpdateProgress2");
    timeoutID = window.setTimeout(function () { updateProgress.set_visible(true); }, 100);
    return true;
    
    function hideUpdateProgress()
    {
        clearTimeout(timeoutID);
        updateProgress = $find("UpdateProgress2");
        updateProgress.set_visible(false);
    }
    

    要调用hideUpdateProgress();,可以在mtdCreatePDF函数的末尾添加这一行。

    ClientScript.RegisterStartupScript(Page.GetType(), 
        "hideUpdateProgress",
        "hideUpdateProgress();",
        true);
    

    【讨论】:

    • 谢谢,我试过了,但在 mtdCreatePDF 函数末尾应用的 ClientScript.RegisterStartupScript 没有任何反应。 hideUpdateProgress 不会被触发,当 Response.Flush 或 Response.End 调用时,所有后续指令都会被忽略。
    【解决方案2】:

    我通过以下方式解决了它:我将所有内容都移到了客户端。

    A.我在点击链接按钮时添加了一个客户端事件

    <asp:LinkButton ID="LinkButton6" OnClientClick="return TestPDFDEF();" runat="server" CssClass="btn btn-small btn-primary fullwidth"><i class="icon icon-ok"></i>&nbsp;TEST PDF WebService Def</asp:LinkButton>
    

    B.我在页面中添加了一个 WebMethod,为 Ajax 调用提供了一个 [byte] 类型的变量

    [WebMethod]
            [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
            public byte[] GetPDF(List<Classes.GridCosts> MyGrid)
    {
    
         foreach (Classes.GridCosts rowsGrid in GrMyGridglia)
            {
                Console.Write(rowsGrid.Field1);
                Console.Write(rowsGrid.Field2);
    
            }
    
       string suffix = @"Pdf_PRODOTTI\Print.pdf";
       string nameTGT = HttpContext.Current.Server.MapPath("~") + suffix;
       var stream = new MemoryStream();
       var writer = new PdfWriter(stream);
       var pdf = new PdfDocument(writer);
       var document = new Document(pdf);
       document.Add(new Paragraph("Hello world!"));
       document.Close();
    
       return stream.ToArray();
     }
    

    C.我已经定义了一个类来接收将传递给方法的网格

     public class GridCosts 
    {
            public string Field1{ get; set; }
            public string Field2{ get; set; }
    }
    

    D.添加了显示沙漏的图像:

    $(document).ready(function () {
    
    $('body').append('<div class="progress" id="ajaxBusy"><p><img src="../images/ajax-loader.gif">&nbsp;Waiting..</p></div>');
    $('#ajaxBusy').hide();
    
    //$('#ajaxBusy').css({
    //    display: "none",
    //    left: "50%",
    //    margin: "0px",
    //    paddingLeft: "0px",
    //    paddingRight: "0px",
    //    paddingTop: "0px",
    //    paddingBottom: "0px",
    //    position: "fixed",
    //    right: "3px",
    //    top: "35%",
    //    width: "auto"
    //});
    
    // Ajax activity indicator bound to ajax start/stop document events
    $(document).ajaxStart(function () {
        $('#ajaxBusy').show();
    }).ajaxStop(function () {
        $('#ajaxBusy').hide();
    });
    
    });
    

    E.我使用 Javascript 将 B 点中提到的变量发送给用户

    function TestPDFDEF() {
    $(function () {
    
        var MyGrid= new Array();
    
        var CostsRow = {};
        $('[id*=MyGrid]').find('tr:has(td)').each(function () {
            CostsRow.Field1= $.trim($(this).find("td:nth-child(3)").text());
            CostsRow.Field2= $.trim($(this).find("td:nth-child(4)").text());
            MyGrid.push(CostsRow );
            CostsRow = {};
        });
    
            type: "POST",
            url: "WebService1.asmx/GetPDF",
            contentType: "application/json; charset=utf-8",
            data: '{MyGrid: ' + JSON.stringify(MyGrid) + '}',
            dataType: "json",
            beforeSend: function () {
            },
            success: function (data) {
                data = data.d;
                var byteArray = new Uint8Array(data);
                var a = window.document.createElement('a');
                a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/pdf' }));
                a.download = 'FileName';
                document.body.appendChild(a)
                a.click();
                document.body.removeChild(a)
    
            },
            complete: function (data) {
                
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                
                alert(textStatus);
            }
        });
    
    
    
    });
    

    }

    【讨论】:

      猜你喜欢
      • 2011-03-25
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多