Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display local html file content in UWP WebView

I believe this is pretty straightforward task and I've seen a lot of examples in the web but still none of them is working for me since I experience different exceptions.

html:

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>
        Help html content.
    </p>
</body>
</html>

xaml:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>

        <WebView x:Name="webView" />
        <Button x:Name="buttonRefresh" 
                Grid.Row="1" 
                HorizontalAlignment="Center"
                Click="buttonRefresh_Click">
            Refresh
        </Button>
    </Grid>

To display static html saved in help.html file in my UWP application LocalFolder I've already tried the following:
- Use Navigate method:

private void buttonRefresh_Click(object sender, RoutedEventArgs e)
        {
            var uri = new Uri("ms-appdata:///local/help.html");
            webView.Navigate(uri);
        }

and the result is the following exception:

System.ArgumentException: Value does not fall within the expected range.
   at Windows.UI.Xaml.Controls.WebView.Navigate(Uri source)
   at SimpleUwpApp.Proxy.SimplerPage.buttonRefresh_Click(Object sender, RoutedEventArgs e)


- Try to set Source property of webView explicitly in code behind:

private void buttonRefresh_Click(object sender, RoutedEventArgs e)
{
    var uri = new Uri("ms-appdata:///local/help.html");
    webView.Source = uri;
}

result:

System.ArgumentException: Value does not fall within the expected range.
   at Windows.UI.Xaml.Controls.WebView.put_Source(Uri value)
   at SimpleUwpApp.Proxy.SimplerPage.buttonRefresh_Click(Object sender, RoutedEventArgs e)


- Set Source property of webView explicitly in xaml: This is the exact example from microsoft documentation.

<WebView x:Name="webView" Source="ms-appdata:///local/help.html" />

As a result exception on startup:

Windows.UI.Xaml.Markup.XamlParseException: The text associated with this error code could not be found.

Failed to assign to property 'Windows.UI.Xaml.Controls.WebView.Source' because the type 'Windows.Foundation.String' cannot be assigned to the type 'Windows.Foundation.Uri'. [Line: 16 Position: 54]
   at Windows.UI.Xaml.Application.LoadComponent(Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at SimpleUwpApp.Proxy.SimplerPage.InitializeComponent()


- Tried using url string directly in Navigate() arguments as in this microsoft examples but Navigate() accepts only Uri as an aargument so the documentation is either invalid, either for older version of xaml toolkit.

webView.Navigate("ms-appx-web:///help.html");

result:

Syntax error.

The only solution I've temporary came up with is reading the content of html file with some kind of file manager and using NavigateToString() method:

var content = fileManager.Read("help.html"); // Manually read the content of html file
webView.NavigateToString(content);


So the question is why described examples don't work? How to avoid using NavigateToString?

like image 291
Dmytro Avatar asked Feb 23 '17 14:02

Dmytro


2 Answers

So i got two different things, which worked for me:

The XAML-version:

<WebView x:Name="webView" Source="ms-appx-web:///help.html"/>

Here you need to use the ms-appx-web prefix.

The code-behind version:

webView.Navigate(new Uri("ms-appx-web:///help.html"));

The difference to your version is, that you are not allowed to enter the string only. You need to create a new Object of the Uri-Class.

In both versions, the html-file is a direct child of the project and the project is a Windows-10-UWP Application [You didnt say, if you use Windows 8 or Windows 10]

like image 144
TheTanic Avatar answered Oct 23 '22 11:10

TheTanic


The solution provided by TheTanic will work for files that are delivered with your package. For files stored in your LocalFolder or TemporaryFolder you must follow special URI scheme:

The WebView support for this scheme requires you to place your content in a subfolder under the local or temporary folder. This enables navigation to Uniform Resource Identifier (URI) such as ms-appdata:///local/folder/file.html and ms-appdata:///temp/folder/file.html

This means that if you use LocalFolder then URI will start like this: ms-appdata:///local/ after this must be a folder and inside your file. Here is a working sample:

StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///help.html"));
StorageFolder folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("anyFolder", CreationCollisionOption.OpenIfExists);
await file.CopyAsync(folder, "help.html", NameCollisionOption.ReplaceExisting);
webView.Navigate(new Uri("ms-appdata:///local/anyFolder/help.html"));

Note also that all the content used must be also in that folder as:

Each of these first-level subfolders is isolated from the content in other first-level subfolders.

like image 43
Romasz Avatar answered Oct 23 '22 11:10

Romasz