可以从.NET MAUI包装器的BlazorWebView返回PDF文件吗?

huangapple go评论54阅读模式
英文:

Can I return a PDF file from a BlazorWebView in a .NET MAUI wrapper?

问题

我正在构建一个需要在iOS和Play Store上发布的APP。

技术栈

.NET MAUI Blazor项目,整个应用程序在BlazorWebView内呈现。所有数据都通过API检索。

问题陈述

我有一个包含多个PDF下载的页面。我希望应用程序打开设备上安装的默认PDF应用程序。这可能吗?

我的尝试

我尝试了经典的Blazor WASM方式,使用了一个JavaScript函数(在没有MAUI包装的情况下可以正常工作),但在当前设置中不起作用。没有错误,应用程序只是不返回文件。MAUI / Blazor社区的任何提示都非常受欢迎。我希望避免编写原生代码。

我分享了我当前的方法(在没有MAUI包装的情况下可以正常工作)

C#

public async Task<File> DownloadPdf(string url, string name)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            var file = await response.Content.ReadAsByteArrayAsync();
            await JS.InvokeVoidAsync("BlazorDownloadFile", "update.pdf", "application/pdf", file);
        }
    }
}

Javascript

window.BlazorDownloadFile = (filename, contentType, content) => {
        // Create the URL
        const file = new File([content], filename, { type: contentType });
        const exportUrl = URL.createObjectURL(file);

        // Create the <a> element and click on it
        const a = document.createElement("a");
        document.body.appendChild(a);
        a.href = exportUrl;
        a.download = filename;
        a.target = "_self";
        a.click();

        // We don't need to keep the object URL, let's release the memory
        // On older versions of Safari, it seems you need to comment this line...
        URL.revokeObjectURL(exportUrl);
    }
英文:

I'm building an APP which need to be published in both the IOS & Play Store.

Tech Stack

.NET MAUI Blazor project, the entire app is rendered inside a BlazorWebView. All data is retrieved via an API.

Problem statement

I have a page which contains multiple PDF downloads. I want the app to open the default PDF app installed on that device. Is this possible?

My attempts

I've tried the classic Blazor WASM way by using a javascript function (this works without MAUI wrapper), but it's not working in the current setup. No error, the app just doesn't return a file. Any tips from the MAUI / Blazor community are very welcome. I want to avoid having to write native code.

I'm sharing my current approach (which works in WASM without the MAUI wrapper)

C#

public async Task&lt;File&gt; DownloadPdf(string url, string name)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            var file = await response.Content.ReadAsByteArrayAsync();
            await JS.InvokeVoidAsync(&quot;BlazorDownloadFile&quot;, $&quot;update.pdf&quot;, &quot;application/pdf&quot;, file);
        }
    }
}

Javascript

window.BlazorDownloadFile = (filename, contentType, content) =&gt; {
        // Create the URL
        const file = new File([content], filename, { type: contentType });
        const exportUrl = URL.createObjectURL(file);

        // Create the &lt;a&gt; element and click on it
        const a = document.createElement(&quot;a&quot;);
        document.body.appendChild(a);
        a.href = exportUrl;
        a.download = filename;
        a.target = &quot;_self&quot;;
        a.click();

        // We don&#39;t need to keep the object URL, let&#39;s release the memory
        // On older versions of Safari, it seems you need to comment this line...
        URL.revokeObjectURL(exportUrl);
    }

答案1

得分: 0

I have solved it with the information found here: https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/launcher?tabs=android

If anyone needs it, this is my adjusted code which opens the PDF in the correct app!

if (response.IsSuccessStatusCode)
{
    IsDownloading = true;

    var pdfByteArray = await response.Content.ReadAsByteArrayAsync();

    // cache the file
    string file = System.IO.Path.Combine(FileSystem.CacheDirectory, $"{name.Replace(" ", "-")}.pdf");
    await System.IO.File.WriteAllBytesAsync(file, pdfByteArray);

    IsDownloading = false;
    await Launcher.Default.OpenAsync(new OpenFileRequest(name, new ReadOnlyFile(file)));
}
英文:

I have solved it with the information found here: https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/launcher?tabs=android

If anyone needs it, this is my adjusted code which opens the PDF in the correct app!

        if (response.IsSuccessStatusCode)
        {
            IsDownloading = true;

            var pdfByteArray = await response.Content.ReadAsByteArrayAsync();

            // cache the file
            string file = System.IO.Path.Combine(FileSystem.CacheDirectory, $&quot;{name.Replace(&quot; &quot;, &quot;-&quot;)}.pdf&quot;);
            await System.IO.File.WriteAllBytesAsync(file, pdfByteArray);

            IsDownloading = false;
            await Launcher.Default.OpenAsync(new OpenFileRequest(name, new ReadOnlyFile(file)));
        }

huangapple
  • 本文由 发表于 2023年5月10日 22:03:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76219371.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定