You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server中Bootstrap OffCanvas内TelerikPDFViewer内容不刷新问题

问题描述

在Blazor Server项目中,我将Telerik PDFViewer控件嵌套在Blazor Bootstrap的OffCanvas控件内。点击表格行内按钮需完成以下操作:

  • 获取当前行的条目ID,调用方法获取生成PDF的数据
  • 将PDF数据赋值给绑定到Telerik PDFViewer的对象
  • 调用OffCanvas的ShowAsync()方法显示面板以展示PDF

遇到的异常情况:使用await调用ShowAsync()时,PDF内容无法刷新;移除await关键字后则能正常刷新。首次调用PDF显示正常,但点击其他行按钮时PDF内容保持不变,去掉await后每次点击都能正确加载对应行的PDF。

触发按钮的处理方法代码如下:

private async Task ViewTOPCasePDFHandler(GridCommandEventArgs args)
{
    TOPCase item = args.Item as TOPCase; // 获取点击了「查看PDF」按钮的行数据        
    string pdfBase64String = await _topService.GenerateFormCompletedPDF(item.CaseID); // 调用方法获取PDF内容        
    pdfViewerModel = new PdfViewerModel() // 将PDF内容赋值给绑定到Telerik PDFViewer的模型
         {
             PdfSource = Convert.FromBase64String(pdfBase64String),
             DownloadFilename = Convert.ToDateTime(item.CreatedDate).ToString("yyyy_MM_dd") + "_MyForm_" + item.CaseID.ToString()
         };

    await pdfViewerWindow.ShowAsync(); // 显示OffCanvas面板
}
原因分析

这是Blazor Server的组件渲染时机与异步操作顺序冲突导致的:

  • 使用await ShowAsync()时,该异步方法会优先触发OffCanvas的UI更新,此时Blazor的渲染上下文尚未完成pdfViewerModel的状态变更同步,导致PDFViewer读取的仍是旧模型数据。
  • 移除await后,ShowAsync()会作为“火并忘”的异步操作执行,此时pdfViewerModel的赋值先完成,状态变更通知Blazor触发重新渲染,之后OffCanvas才显示,PDFViewer能获取到最新的模型数据。

但直接去掉await可能引发潜在的异步异常问题,更稳妥的做法是确保状态更新先被Blazor捕获,再触发面板显示。

解决方案

推荐以下两种可靠的解决方式:

  1. 强制触发状态更新后再显示面板
    在赋值pdfViewerModel后,调用StateHasChanged()通知Blazor立即同步状态,再执行面板显示操作:
private async Task ViewTOPCasePDFHandler(GridCommandEventArgs args)
{
    TOPCase item = args.Item as TOPCase;        
    string pdfBase64String = await _topService.GenerateFormCompletedPDF(item.CaseID);        
    pdfViewerModel = new PdfViewerModel()
         {
             PdfSource = Convert.FromBase64String(pdfBase64String),
             DownloadFilename = Convert.ToDateTime(item.CreatedDate).ToString("yyyy_MM_dd") + "_MyForm_" + item.CaseID.ToString()
         };

    StateHasChanged(); // 强制通知Blazor更新状态
    await Task.Delay(1); // 给渲染流程预留极短时间(可选,视实际情况调整)
    await pdfViewerWindow.ShowAsync();
}
  1. 使用InvokeAsync包裹状态更新与显示逻辑
    利用Blazor的InvokeAsync确保所有操作在正确的渲染上下文中执行:
private async Task ViewTOPCasePDFHandler(GridCommandEventArgs args)
{
    TOPCase item = args.Item as TOPCase;        
    string pdfBase64String = await _topService.GenerateFormCompletedPDF(item.CaseID);        

    await InvokeAsync(() =>
    {
        pdfViewerModel = new PdfViewerModel()
        {
            PdfSource = Convert.FromBase64String(pdfBase64String),
            DownloadFilename = Convert.ToDateTime(item.CreatedDate).ToString("yyyy_MM_dd") + "_MyForm_" + item.CaseID.ToString()
        };
        return pdfViewerWindow.ShowAsync();
    });
}

内容的提问来源于stack exchange,提问作者gib_stu01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:15:56