1

The UWP WebView control has a Refresh() method that works fine for most pages, but calling the method directly after the WebView has been navigated somewhere by POST (e.g. a form submission inside the WebView itself) raises the NavigationStarted event, but never actually performs any refresh.

Here's some minimised XAML that demonstrates the issue:

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Button Grid.Row="0" Name="Refresh" Click="Refresh_Click" Content="Refresh" />
        <WebView Grid.Row="1" Name="BrowserView" />
    </Grid>
</Page>

Here's the relevant code-behind:

namespace App1
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            BrowserView.NavigationCompleted += BrowserView_NavigationCompleted;
            BrowserView.NavigationStarting += BrowserView_NavigationStarting;
            BrowserView.Navigate(new Uri("http://localhost/test.php"));
        }

        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            BrowserView.Refresh();
        }

        private void BrowserView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
        {
            // Always called on first load and when refreshed (even for POST results)
            Debug.WriteLine($"Navigation starting for URI {args.Uri}");
        }

        private void BrowserView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
        {
            // Not called when a POST result is being refreshed
            Debug.WriteLine($"Navigation completed");
        }
    }
}

As a test, I've created and hosted a very small PHP page with the following content and hosted it at http://localhost/test.php:

<!DOCTYPE html>
<html>
<head>
 <title>Test</title>
</head>
<body>
 <form method="POST">
   <p>Page loaded at <?php echo date('H:i:s') . (!empty($_POST['in']) ? ' with text "'.htmlspecialchars($_POST['in']).'"' : '') ?></p>
   <input type="text" name="in" />
   <input type="submit" />
 </form>
</body>
</html>

Once I point my WebView at this page I can refresh the page on the initial load just fine, but after submitting the form, Refresh() raises the NavigationStarting event but does not navigate the page at all (as indicated by the timestamp on the test PHP result not changing) and never raises a corresponding NavigationCompleted event.

When the same page is visited in Edge, the user is shown this warning when attempting to refresh a POST result:

The dialog Microsoft Edge shows to users when refreshing a page submitted by POST

Choosing Retry resubmits the POST data to the server, and choosing Cancel behaves similarly to what I'm seeing (doing nothing at all). This dialog is obviously not emulated in any way by the UWP WebView control.

Since my actual application shows users a refresh button, I need the button to do something regardless of whether or not they've recently submitted a form, or alternatively I need to disable the refresh button so it's not confusing to users when the button does nothing.

Right now the only solution I have (which astonishingly seems to work, but is really nasty) is to call GoBack(), then in the NavigationCompleted event handler immediately call GoForward().

I could settle for an option that allows me to detect this condition (something like WebView.CanRefresh so that I could disable my Refresh button), or worst case scenario some kind of result/exception that allows me to communicate to the user what has (not) happened and why.

Kit Grose
  • 1,792
  • 16
  • 16

1 Answers1

0

If I understand your question correctly, you want to refresh the page after form has been submitted.

If so, you could check if the form has been submitted in php handler. Please check this thread: Checking if form has been submitted - PHP. Then, in the php handler, you could call the javascript method to refresh the page like window.location.reload().

Xie Steven
  • 8,544
  • 1
  • 9
  • 23
  • Thanks Xavier. I am trying to improve the behaviour of the UWP app pointing at a page I don’t Control (the PHP example is just for reproduction instructions). – Kit Grose Sep 04 '18 at 03:09
  • How did you call the `WebView.Refresh()` method after submitting the form? Please provide a [mcve]. – Xie Steven Sep 04 '18 at 05:45
  • I call `WebView.Refresh()` in the button click handler for a button in the same XAML page as the web view itself. I've updated the question to make it more complete to hopefully clarify my issue. – Kit Grose Sep 04 '18 at 07:33
  • When you submit the form to `http://localhost/test.php`, did the php page will do response? – Xie Steven Sep 05 '18 at 08:36
  • Yes, the PHP page updates when the form is submitted (updating the timestamp and printing out any name I entered), but not when the user presses the refresh button. – Kit Grose Sep 05 '18 at 08:38