Still, explain if anyone knows why body = null.
That is why:
Thread.Sleep(10000); //думал мб не хватает времени прогрузить
Use Thread.Sleep to wait for the document to load. WebBrowser - a wrapper over an Internet Explorer ActiveX element that needs to process messages in a GUI stream in order to work correctly. Calling Thread.Sleep blocks it, so that although the document has time to load the "transport layer" in 10 seconds, WebBrowser cannot react to this and set the value of the Document property. For everything to work, you need to wait without interrupting message processing.
Unfortunately, WinForms is a very old library and in WebBrowser I could not find an asynchronous loading method that would allow using await . So the only (standard) way is to subscribe to an event:
private void button1_Click(object sender, EventArgs e) { System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser(); browser.ScriptErrorsSuppressed = true; browser.DocumentCompleted += browser_DocumentCompleted; browser.Navigate("https://temp-mail.org/ru"); } void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { MessageBox.Show((sender as WebBrowser).Document.Body.InnerHtml); }
To implement wait more conveniently, create a helper method to wait for an event using a TaskCompletionSource :
using System; using System.Reflection; using System.Threading.Tasks; namespace WinformsTest { public class AsyncTools { /// <summary> /// Получает объект Task, который может использоваться для ожидания срабатывания указанного события /// </summary> /// <param name="o">Объект-источник события</param> /// <param name="evt">Имя события</param> public static Task<object> GetTaskFromEvent(object o, string evt) { if (o == null || evt == null) throw new ArgumentNullException("Please pass non-null arguments"); EventInfo einfo = o.GetType().GetEvent(evt); if (einfo == null) { throw new ArgumentException(String.Format("*{0}* has no *{1}* event", o, evt)); } TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); MethodInfo mi = null; Delegate deleg = null; EventHandler handler = null; //код обработчика события handler = (s, e) => { mi = handler.Method; deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi); einfo.RemoveEventHandler(s, deleg); //отцепляем обработчик события tcs.TrySetResult(null); //сигнализируем о наступлении события }; mi = handler.Method; deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi); //получаем делегат нужного типа einfo.AddEventHandler(o, deleg); //присоединяем обработчик события return tcs.Task; } } }
Then waiting for the download of the document can be done using await (.NET 4.5+):
var task = AsyncTools.GetTaskFromEvent(webBrowser1,"DocumentCompleted"); webBrowser1.Navigate("http://example.com/"); await task;