c# - WinRT/Metro/WSA 向 WebView 提供来自 ZipArchive 的流的问题

标签 c# webview windows-runtime microsoft-metro windows-store-apps

我需要提供一个包含本地存储的 zip 文件内容的 WebView。

我使用NavigateToLocalStreamUri()方法并以与 Windows 库链接 NavigateToLocalStreamUri() 上找到的示例相同的方式提供我自己的扩展 UriResolver .

但是,调试失败得相当惊人,因为“NTLSUri”方法无法识别流的类型并尝试对其进行强制转换。有谁知道如何正确地将流从压缩存档元素提供给 WebView?

详细信息如下:

这是我自己定制的 GetContent() 方法,用于向存档元素提供流,而不是普通的流。

private async Task<IInputStream> GetNormalZipEntryStream(String archivePath)
    {
        StorageFolder current = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("bookTest");

        bookSourceFile = await current.GetItemAsync("testBook.zip") as StorageFile;

        if (archivePath.ElementAt(0) == '/') archivePath = archivePath.Remove(0, 1);

        Stream bookZipStream = await bookSourceFile.OpenStreamForReadAsync();
        ZipArchive bookArchive = new ZipArchive(bookZipStream, ZipArchiveMode.Read);
        ZipArchiveEntry bookContentFile = bookArchive.GetEntry(archivePath);

        if (bookContentFile == null)
            throw new Exception("Invalid archive entry");
        else
        {
            try
            {
                IInputStream stream = bookContentFile.Open().AsInputStream();
                return stream;
            }
            catch (Exception ex)
            {
                var streamConvErr = ex.Message;
            }
        }
        return null;
    }

现在,一切正常,我能够成功地将流获取到存档元素。我还确认 ArchiveElement.Open() 方法确实返回包含“未压缩”内容的流。

问题是 - 在幕后 - NavigateToStreamUri() 方法无法接受 bookContentFile.Open().AsInputStream() 返回的 IInput 流。

它会导致调试器在以下代码部分中断:

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
        UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
        };

此时 e(异常(exception))声明“无效转换操作”。

还要注意,在调试过程中,在调用 AsInputStream() 时,流的类型并不像人们预期的那样:IInputStream 类型,而是 System.IO.NetFxToWinRtStreamAdapter.InputStream 类型

进一步扩展对象,将非公共(public)成员“ManagedStream”视为 System.IO.Compression.DeflateStream 类型

我假设有一些方法可以使用 DataReader 将流转换为内存流,然后转换回 IInputstream,但这似乎违反直觉,因为提供的 AsInpuSream() 方法应该按预期工作。

最佳答案

据我所知,似乎没有办法绕过 IInputStream() 返回类型为:System.IO.NetFxToWinRtStreamAdapter 的流。输入流

我编写了以下方法来手动将字节复制到新流中,仅使用 Windows.Storage.Stream 类型。 WebView 没有任何提示,一切正常

private async Task<IInputStream> GetInputStreamFromIOStream(System.IO.Stream stream, long fileSize)
    {
        try
        {
            BinaryReader binReader = new BinaryReader(stream);
            byte[] byteArr = binReader.ReadBytes((int)fileSize);

            var iMS = new InMemoryRandomAccessStream();
            var imsOutputStream = iMS.GetOutputStreamAt(0);
            DataWriter dataWriter = new DataWriter(imsOutputStream);
            dataWriter.WriteBytes(byteArr);

            await dataWriter.StoreAsync();
            await imsOutputStream.FlushAsync();

            return iMS.GetInputStreamAt(0);
        }
        catch(Exception ex)
        {
            //Error Handling here
            return null;
        }
    }

有兴趣的人可以通过以下方式实现:

        sourceFile = await current.GetItemAsync("zipfileHere.zip") as StorageFile;
        Stream zipStream = await sourceFile.OpenStreamForReadAsync();
        ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
        ZipArchiveEntry contentFile = archive.GetEntry(archivePathVar);

        if (contentFile == null)
            throw new Exception("Invalid archive entry");
        else
        {
            try
            {
                var zipASize = contentFile.Length;
                IInputStream stream = await GetInputStreamFromIOStream(contentFile.Open(), zipASize);

                return stream;
            }
            catch (Exception ex)
            {
                //Some error handling here
            }

        }

关于c# - WinRT/Metro/WSA 向 WebView 提供来自 ZipArchive 的流的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22251075/

相关文章:

c# - 忽略序列化为 JSON 时抛出异常的类成员

c# - 必须声明标量变量 “@Login” 。尝试向 SqlDataSource 添加参数时出错

c# - Interlocked.Increment vs lock in debug vs release mode

Android webview地理定位数据库打开失败

javascript - Android WebView 在加载 html 之前注入(inject) Javascript

c# - 数据绑定(bind)到列数未知的网格

android - 带有 FragmentStatePagerAdapter 的 WebView 在调用 setCurrentItem 时变为空白

c# - 无法激活 Windows 应用商店应用程序(Visual Studio 2015,Windows 10 版本 1511)

xaml - Metro XAML-LayoutTransform在哪里?

c# - 如何从 HttpClientHandler.CookieContainer 获取 cookie