Reputation: 11
I'm trying to display a PDF file in my packaged WinUI3 application using PDF.js and WebView2, but I'm encountering an issue where the PDF doesn't render, and I get a "File not found" error within the WebView2 control.
private async void PickAFileButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
var window = App.MainWindow;
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.FileTypeFilter.Add(".pdf");
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{
await PdfWebView.EnsureCoreWebView2Async();
var pdfjsPath = Path.Combine(AppContext.BaseDirectory, "Assets", "pdfjs");
PdfWebView.CoreWebView2.SetVirtualHostNameToFolderMapping(
"appassets", pdfjsPath,CoreWebView2HostResourceAccessKind.Allow);
var pdfFilePath = new Uri($"file:///{file.Path}");
var pdfjsViewerUri = "ms-appx-web:///Assets/pdfjs/web/viewer.html";
var encodedFilePath = Uri.EscapeDataString(pdfFilePath.AbsoluteUri);
PdfWebView.Source = new Uri($"{pdfjsViewerUri}?file={encodedFilePath}");
}
}
WebView2 Source: ms-appx-web:///Assets/pdfjs/web/viewer.html?file=file%3A%2F%2F%2FC%3A%2MyTest%2F2024%2F07%2F01%2Ffolder%2520test%2Ffiles%2520and%2520pdf%2F300.pdf
Any ideas on why the PDF is not rendering and how to fix this issue?
Upvotes: 1
Views: 122
Reputation: 333
I did try to use webview2 to render PDF with following sample code. You need to read the local file into byte[] array.
private void ShowPDFInWebView2(byte[] data)
{
string htmTemplate = @"<!DOCTYPE html><html><head><meta charset='UTF-8'><style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.embed-container {
height: 100%;
}
.embed-container embed {
width: 100%;
height: 100%;
}
</style></head>" +
"<body><div class='embed-container'><embed src='#srccontent#' type='application/pdf' /></div></body></html>";
htmTemplate = htmTemplate.Replace("#srccontent#", "data:application/pdf;base64," + Convert.ToBase64String(data));
pdfViewer2.NavigateToString(htmTemplate);
}
Upvotes: 0
Reputation: 4387
To load local content in WebView2 you have a number of options which are discussed in the linked doc:
Scenario | file URL | HTML string | virtual host name map | WebResourceRequested |
---|---|---|---|---|
Origin-based DOM APIs | ✔️ | ❌ | ✔️ | ✔️ |
DOM APIs requiring secure context | ❌ | ❌ | ✔️ | ✔️ |
Dynamic content | ❌ | ✔️ | ❌ | ✔️ |
Additional web resources | ✔️ | ❌ | ✔️ | ✔️ |
Additional web resources resolved in WebView2 process | ✔️ | ❌ | ✔️ | ❌ |
In your case you are attempting to use ms-appx-web
which is a URI scheme supported by the previous WebView control but not by WebView2. The closest WebView2 supported mechanism is the virtual host name mapping.
You are already setting up that mapping so you need to use it instead of ms-appx-web
:
PdfWebView.Source = new Uri($"https://appassets/web/viewer.html?file={encodedFilePath}");
Upvotes: 0