问题
I've got a windows form in Visual Studio 2008 using .NET 3.5 which has a WebBrowser control on it. I need to analyse the form's PostData in the Navigating event handler before the request is sent. Is there a way to get to it?
The old win32 browser control had a Before_Navigate event which had PostData as one of its arguments. Not so with the new .NET WebBrowser control.
回答1:
That functionality isn't exposed by the .NET WebBrowser control. Fortunately, that control is mostly a wrapper around the 'old' control. This means you can subscribe to the BeforeNavigate2 event you know and love(?) using something like the following (after adding a reference to SHDocVw to your project):
Dim ie = DirectCast(WebBrowser1.ActiveXInstance, SHDocVw.InternetExplorer)
AddHandler ie.BeforeNavigate2, AddressOf WebBrowser_BeforeNavigate2
...and do whatever you want to the PostData inside that event:
Private Sub WebBrowser_BeforeNavigate2(ByVal pDisp As Object, ByRef URL As Object, _
ByRef Flags As Object, ByRef TargetFrameName As Object, _
ByRef PostData As Object, ByRef Headers As Object, ByRef Cancel As Boolean)
Dim PostDataText = System.Text.Encoding.ASCII.GetString(PostData)
End Sub
One important caveat: the documentation for the WebBrowser.ActiveXInstance property states that "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.". In other words: your use of the property may break your app at any point in the future, for example when the Framework people decide to implement their own browser component, instead of wrapping the existing SHDocVw COM one.
So, you'll not want to put this code in anything you ship to a lot of people and/or anything that should remain working for many Framework versions to come...
回答2:
C# version
/// <summary>
/// Fires before navigation occurs in the given object (on either a window or frameset element).
/// </summary>
/// <param name="pDisp">Object that evaluates to the top level or frame WebBrowser object corresponding to the navigation.</param>
/// <param name="url">String expression that evaluates to the URL to which the browser is navigating.</param>
/// <param name="Flags">Reserved. Set to zero.</param>
/// <param name="TargetFrameName">String expression that evaluates to the name of the frame in which the resource will be displayed, or Null if no named frame is targeted for the resource.</param>
/// <param name="PostData">Data to send to the server if the HTTP POST transaction is being used.</param>
/// <param name="Headers">Value that specifies the additional HTTP headers to send to the server (HTTP URLs only). The headers can specify such things as the action required of the server, the type of data being passed to the server, or a status code.</param>
/// <param name="Cancel">Boolean value that the container can set to True to cancel the navigation operation, or to False to allow it to proceed.</param>
private delegate void BeforeNavigate2(object pDisp, ref dynamic url, ref dynamic Flags, ref dynamic TargetFrameName, ref dynamic PostData, ref dynamic Headers, ref bool Cancel);
private void Form1_Load(object sender, EventArgs e)
{
dynamic d = webBrowser1.ActiveXInstance;
d.BeforeNavigate2 += new BeforeNavigate2((object pDisp,
ref dynamic url,
ref dynamic Flags,
ref dynamic TargetFrameName,
ref dynamic PostData,
ref dynamic Headers,
ref bool Cancel) => {
// Do something with PostData
});
}
C# WPF version
Keep the above, but replace:
dynamic d = webBrowser1.ActiveXInstance;
with:
using System.Reflection;
...
PropertyInfo prop = typeof(System.Windows.Controls.WebBrowser).GetProperty("ActiveXInstance", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo getter = prop.GetGetMethod(true);
dynamic d = getter.Invoke(webBrowser1, null);
来源:https://stackoverflow.com/questions/141626/how-can-i-access-postdata-from-webbrowser-navigating-event-handler