.NET MAUI Blazor Hybrid中BlazorBootstrap PdfViewer仅加载一次PDF的问题
.NET MAUI Blazor Hybrid中Blazor Bootstrap PdfViewer二次加载报错解决
场景与问题
在.NET MAUI Blazor Hybrid应用中,通过如下导航链接跳转到PharmakaPdfViewer组件:
<NavLink href="@($"PharmakaPdfViewer/{row.Id}")" Match="NavLinkMatch.Prefix">...</NavLink>
PharmakaPdfViewer组件原始代码如下:
@page "/pharmakapdfviewer/{id}" <h3>PharmakaPdfViewer @Id</h3> <PdfViewer Class="mb-3" Url="@link" /> @code { [Parameter] public string? Id { get; set; } private string? link = string.Empty; protected override async Task OnInitializedAsync() { var serviceClient = new APIServiceClient(); var dataRow = await serviceClient.GetDataRowAsync(Int32.Parse(Id)); link = dataRow.Link; await base.OnInitializedAsync(); } }
该组件使用Blazor Bootstrap的PdfViewer,通过异步调用SOAP服务获取PDF文件URL并赋值给link,首次加载时PDF可正常显示,但返回链接列表后再次点击任意导航链接(包括同一ID),控制台会抛出如下错误:
Invalid parameter object: need either .data, .range or .url Error: Invalid parameter object: need either .data, .range or .url at Module.getDocument (https://0.0.0.0/_content/Blazor.Bootstrap/pdfjs-4.0.379.min.js:21:46398) at Module.initialize (https://0.0.0.0/_content/Blazor.Bootstrap/blazor.bootstrap.pdf.js:202:11) at https://0.0.0.0/_framework/blazor.webview.js:1:3050 at new Promise (<anonymous>) at g.beginInvokeJSFromDotNet (https://0.0.0.0/_framework/blazor.webview.js:1:3007) at https://0.0.0.0/_framework/blazor.webview.js:1:48020 at EventTarget.<anonymous> (<anonymous>:7:62) at EmbeddedBrowserWebView.<anonymous> (<anonymous>:1:43835) at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) at Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeVoidAsync(IJSObjectReference jsObjectReference, String identifier, Object[] args) at BlazorBootstrap.PdfViewerJsInterop.InitializeAsync(Object objRef, String elementId, Double scale, Double rotation, String url) at BlazorBootstrap.PdfViewer.OnAfterRenderAsync(Boolean firstRender) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
此时PdfViewer显示为空。
问题原因
Blazor路由导航时,组件实例可能被复用(尤其是返回后再次进入同一路由或路由参数变更时)。原始代码中link初始值设为string.Empty,二次加载时,组件的OnAfterRenderAsync会在OnInitializedAsync完成SOAP请求获取真实URL之前执行,导致PdfViewer的JS互操作初始化时传入空URL,触发pdf.js的参数校验错误。
解决方法
通过条件渲染控制PdfViewer的创建时机,仅当link存在有效值时才渲染组件;同时在初始化阶段主动重置link并触发状态变更,确保旧的PdfViewer实例被销毁,避免复用问题。修改后的代码如下:
@if (!string.IsNullOrEmpty(link)) { <PdfViewer Class="mb-3" Url="@link" /> } @code { [Parameter] public string? Id { get; set; } private string? link; protected override async Task OnInitializedAsync() { // 重置link为null,强制销毁旧的PdfViewer组件 link = null; StateHasChanged(); var serviceClient = new APIServiceClient(); var dataRow = await serviceClient.GetDataRowAsync(Int32.Parse(Id)); link = dataRow.Link; } }
内容的提问来源于stack exchange,提问作者dpant
相关产品推荐
相关产品推荐

