动态合并PDF下载时GridView图标替换代码仅部分生效的排查问询
问题场景
基于GridView中的路径数据构建PDF合并工具,遍历GridView后自动下载合并后的PDF。预期对应文件不存在时,将GridView中的"PDF"图标替换为划掉的"noPDF"图标,但该功能仅在两种场景下生效:
- 所有文件均存在(PDF正常下载);
- 所有文件均不存在(图标替换正常)。
当存在部分文件缺失的情况时,PDF可正常合并生成,但GridView中的图标未按预期替换,需从以下方向排查问题:
相关代码
public void Start_Merge(object sender, EventArgs e) { List<PdfReader> readerList = new List<PdfReader>(); iTextSharp.text.Document document = new iTextSharp.text.Document(); PdfCopy copy = new PdfCopy(document, Response.OutputStream); document.Open(); // loop through every line in Gridview and get the path' to each pdf int missing = 0; for (int row = 0; row < Gridview_Presion.Rows.Count; row++) { Label Path = Gridview_Presion.Rows[row].FindControl("LabelPDFPath") as Label; string path = Path.Text; string filename = Convert.ToString(Gridview_Presion.Rows[row].Cells[14].Text); if (File.Exists(path)) { PdfReader Reader = new PdfReader(path); readerList.Add(Reader); for (int i = 1; i <= Reader.NumberOfPages; i++) { copy.AddPage(copy.GetImportedPage(Reader, i)); } Reader.Close(); } else { missing = missing + 1; Image img = Gridview_Presion.Rows[row].FindControl("img_Cert") as Image; img.ImageUrl = "img/NoPdf.png"; } } string file; file = SALESID.Text + "_CertPres.pdf"; if (missing > 0) { LabelMissingPresCerts.Text = Convert.ToString(missing) + " Certificates missing!"; file = SALESID.Text + "_CertPres_incomplete.pdf"; LB_ReportMissingPresCert.Visible = true; } if (missing != Gridview_Presion.Rows.Count) { document.Close(); Response.ContentType = "application/pdf"; Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.AppendHeader("content-disposition", "attachment;filename=" + file); } else { //* these operations are necessary to avoid the no-page-error in case no file is downloaded string NullPath = @"\\corp.root.int\dax-emea$\DAX\ES75\Documents\Prod\Public\blank.pdf"; PdfReader Reader = new PdfReader(NullPath); Chapter Chapter = new Chapter("Null", 0); document.Add(Chapter); readerList.Add(Reader); copy.AddPage(copy.GetImportedPage(Reader, 1)); Reader.Close(); document.Close(); Response.Clear(); } }
排查方向
下载响应导致页面未刷新:当部分文件缺失时,代码执行了PDF下载逻辑(向
Response.OutputStream写入PDF内容并设置下载头),浏览器会优先处理下载响应,不会重新渲染当前页面。服务器端对GridView图标的修改没有被发送到客户端,所以前端看不到更新。而全文件不存在时执行了Response.Clear(),没有触发下载,页面正常回发刷新,图标更新生效;全文件存在时没有进入缺失分支,图标状态无需修改,因此看起来正常。控件查找未做空值检查:在替换图标时,直接调用
img.ImageUrl但未检查img_Cert是否成功找到。如果某行的FindControl返回null,会抛出异常,若被全局异常处理捕获,会导致后续行的图标更新操作中断。需要添加空值判断:Image img = Gridview_Presion.Rows[row].FindControl("img_Cert") as Image; if (img != null) { img.ImageUrl = "img/NoPdf.png"; }GridView状态被覆盖:若页面生命周期中,
Start_Merge执行后存在重新绑定GridView的逻辑,会覆盖服务器端修改的图标属性。需要确认后续是否有GridView.DataBind()的调用,导致控件状态被重置为初始值。文件存在性判断准确性:部分文件缺失场景下,需确认
File.Exists(path)的判断是否正确。比如路径包含空格、特殊字符,或者应用程序权限不足导致无法访问文件,都会导致判断结果不符合预期。可以在else分支中添加日志,记录缺失的路径,验证判断逻辑是否准确。响应输出顺序问题:修改GridView控件属性后,再向Response输出PDF内容,控件状态的变更没有被包含在响应中。因为Response已经被用于输出PDF,页面的HTML内容无法同时发送。可以考虑拆分操作:先完成图标更新并刷新页面,再通过独立请求触发PDF下载;或者使用AJAX提前完成文件存在性检查并更新图标,再发起下载请求。
内容的提问来源于stack exchange,提问作者Barnabeck

