如何处理WPF WebBrowser控件导航异常

时间:2012-09-06 12:21:29

标签: c# .net wpf

假设WPF WebBrowser control显示了一些导航错误,并且页面未显示。

所以WPF WebBrowser control有例外。

我发现了一些类似的问题here,但这不是我需要的。

实际上我需要一些方法和对象,它有一个例外,可以得到它。

我们如何处理它?<​​/ p>

谢谢!

P.S。 WinForm WebBrowser控件有一些方法......我们可以为WPF WebBrowser控件执行类似的操作吗?

public Form13()
{
     InitializeComponent();

     this.webBrowser1.Navigate("http://blablablabla.bla");

      SHDocVw.WebBrowser axBrowser = (SHDocVw.WebBrowser)this.webBrowser1.ActiveXInstance;
      axBrowser.NavigateError +=
           new SHDocVw.DWebBrowserEvents2_NavigateErrorEventHandler(axBrowser_NavigateError);
}

void axBrowser_NavigateError(object pDisp, ref object URL,
       ref object Frame, ref object StatusCode, ref bool Cancel)
{
     if (StatusCode.ToString() == "404")
     {
         MessageBox.Show("Page no found");
     }
}

P.S。 #2在WPF App下托管WinForm WebBrowser控件不是我认为的答案。

4 个答案:

答案 0 :(得分:10)

我正在努力解决类似的问题。当计算机失去互联网连接时,我们希望以一种很好的方式处理它。

由于缺乏更好的解决方案,我连接了WebBrowser的Navigated事件,并查看文档的url。如果它是re​​s://ieframe.dll我非常有信心发现了一些错误。

也许可以查看文档并查看服务器是否返回404。

private void Navigated(object sender, NavigationEventArgs navigationEventArgs)
{
    var browser = sender as WebBrowser;
    if(browser != null)
    {
        var doc = AssociatedObject.Document as HTMLDocument;
        if (doc != null)
        {
            if (doc.url.StartsWith("res://ieframe.dll"))
            {
                // Do stuff to handle error navigation
            }
        }
    }
}

答案 1 :(得分:6)

这是一个老问题,但由于我刚刚遭受了这个,我虽然也可以分享。首先,我实施了Markus的解决方案,但是由于我们的防火墙重新映射了403个消息页面,所以想要更好一些。

我找到了一个答案here(其他地方最多)建议使用NavigationService,因为它有一个NavigationFailed事件。

在您的XAML中,添加:

<Frame x:Name="frame"/>

在代码隐藏的构造函数中,添加:

frame.Navigated += new System.Windows.Navigation.NavigatedEventHandler(frame_Navigated);
frame.NavigationFailed += frame_NavigationFailed;
frame.LoadCompleted += frame_LoadCompleted;

frame.NavigationService.Navigate(new Uri("http://theage.com.au"));

处理程序现在可以处理导航失败或成功导航:

void frame_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
{
  e.Handled = true;
  // TODO: Goto an error page.
}

private void frame_Navigated(object sender,  System.Windows.Navigation.NavigationEventArgs e)
{
  System.Diagnostics.Trace.WriteLine(e.WebResponse.Headers);
}

BTW:.Net 4.5框架

答案 2 :(得分:2)

此处也可以使用GetAllListAsync()方法。

dynamic

答案 3 :(得分:1)

一段时间以来,我一直在努力解决这个问题。我发现了比接受的答案更干净的方法来处理此问题。检查 res://ieframe.dll 并不总是对我有用。有时在发生导航错误时,文档url为null。

向您的项目添加以下引用:

  1. Microsoft.mshtml
  2. Microsoft.VisualStudio.OLE.Interop
  3. SHDocVw (在COM下,它称为“ Microsoft Internet控件”)

创建以下帮助程序类:

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Windows.Controls;
using System.Windows.Navigation;

/// <summary>
/// Adds event handlers to a webbrowser control
/// </summary>
internal class WebBrowserHelper
{
    [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", Justification = "consistent naming")]
    private static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");

    internal WebBrowserHelper(WebBrowser browser)
    {
        // Add event handlers
        browser.Navigated += this.OnNavigated;

        // Navigate to about:blank to setup the browser event handlers in first call to OnNavigated
        browser.Source = null;
    }

    internal delegate void NavigateErrorEvent(string url, int statusCode);

    internal event NavigateErrorEvent NavigateError;

    private void OnNavigated(object sender, NavigationEventArgs e)
    {
        // Grab the browser and document instance
        var browser = sender as WebBrowser;
        var doc = browser?.Document;

        // Check if this is a nav to about:blank
        var aboutBlank = new Uri("about:blank");
        if (aboutBlank.IsBaseOf(e.Uri))
        {
            Guid serviceGuid = SID_SWebBrowserApp;
            Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;

            IntPtr obj = IntPtr.Zero;
            var serviceProvider = doc as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
            if (serviceProvider?.QueryService(ref serviceGuid, ref iid, out obj) == 0)
            {
                // Set up event handlers
                var webBrowser2 = Marshal.GetObjectForIUnknown(obj) as SHDocVw.IWebBrowser2;
                var webBrowserEvents2 = webBrowser2 as SHDocVw.DWebBrowserEvents2_Event;
                if (webBrowserEvents2 != null)
                {
                    // Add event handler for navigation error
                    webBrowserEvents2.NavigateError -= this.OnNavigateError;
                    webBrowserEvents2.NavigateError += this.OnNavigateError;
                }
            }
        }
    }

    /// <summary>
    /// Invoked when navigation fails
    /// </summary>
    [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "consistent naming")]
    [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "consistent naming")]
    private void OnNavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
    {
        this.NavigateError.Invoke(URL as string, (int)StatusCode);
    }
}

然后在您的窗口类中:

// Init the UI
this.InitializeComponent();
this.WebBrowserHelper = new WebBrowserHelper(this.MyBrowserPane);

// Handle nav error
this.WebBrowserHelper.NavigateError += this.OnNavigateError;