Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表单上的InvokeMember(“提交”)不会重定向浏览器_C#_Winforms_Webbrowser Control - Fatal编程技术网

C# 表单上的InvokeMember(“提交”)不会重定向浏览器

C# 表单上的InvokeMember(“提交”)不会重定向浏览器,c#,winforms,webbrowser-control,C#,Winforms,Webbrowser Control,我使用WebBrowser控件来测试表单提交,在这个特定的例子中,该操作是一个MVC操作,它重定向到另一个结果页 代码非常简单 void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { var parentForm = _my_find_form_function(); parentForm.SetAttribute("action", "http:/

我使用WebBrowser控件来测试表单提交,在这个特定的例子中,该操作是一个MVC操作,它重定向到另一个结果页

代码非常简单

 void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
 {
     var parentForm = _my_find_form_function();

     parentForm.SetAttribute("action", "http://localhost/tests/TestSubmission");
     parentForm.InvokeMember("submit");
 }
在提交(如预期的那样工作)之后,我原以为下一个documentcompleted事件将在加载重定向页面后触发。相反,将加载相同的页面(带有表单)

有什么我遗漏的吗


谢谢

好的,很抱歉耽搁了,我接着讲别的

不管怎样,这真的很粗糙,但你应该能够挑选你需要的东西

最初的想法是从发现

raisedynamicevent方法的工作方式与async nav类似,它在事件发生后监视文档的状态。当再次确定时,返回。应该处理ajax的东西。需要重新考虑一点,问题很多,但希望能帮助一些人

/// the _profileQueue was a queue of URLs i wanted to nav through and find an 
/// form elem and "click" the submit button on
private async void Next()
    {
        Submission res = null;
        if (_profileQueue.TryDequeue(out res))
        {
            // dirty, but hold the details of the url i'm navigating to in the Tag
            _browser.Tag = res;

            var cts = new CancellationTokenSource(Properties.Settings.Default.BrowserNavigationTimeout); // cancel in 10s
            var html = await LoadDynamicPage(res.SiteProfile.URL, cts.Token);

            // this parses the dom once loaded (awaits for the page)
            ProcessSiteProfile();
            Next();
        }
    }

    // navigate and download 
    async Task<string> LoadDynamicPage(string url, CancellationToken token)
    {
        // navigate and await DocumentCompleted
        var tcs = new TaskCompletionSource<bool>();
        WebBrowserDocumentCompletedEventHandler handler = (s, arg) =>
            tcs.TrySetResult(true);

        // i'm keeping the tcs in a concurrentdictionary against the browser object
        // again, this is pretty dirty but obviously felt like i needed it.
        _browserTasks[_browser] = tcs;

        using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: true))
        {

            // nav to page async
            this._browser.DocumentCompleted += handler;
            try
            {
                if (!string.IsNullOrWhiteSpace(url))
                {
                    this._browser.Navigate(url);                 
                    await tcs.Task; // wait for DocumentCompleted
                }
            }
            finally
            {
                this._browser.DocumentCompleted -= handler;
            }
        }

        // get the root element
        var documentElement = this._browser.Document.GetElementsByTagName("html")[0];

        // poll the current HTML for changes asynchronosly
        var html = documentElement.OuterHtml;
        while (true)
        {
            // wait asynchronously, this will throw if cancellation requested
            await Task.Delay(Properties.Settings.Default.BrowserNavigationWait, token);

            // continue polling if the WebBrowser is still busy
            if (this._browser.IsBusy)
                continue;

            var htmlNow = documentElement.OuterHtml;
            if (html == htmlNow)
                break; // no changes detected, end the poll loop

            html = htmlNow;
        }

        // consider the page fully rendered 
        token.ThrowIfCancellationRequested();

        // remove from task dictionary
        _browserTasks[this._browser] = null;

        return html;
    }

    async void ProcessSiteProfile()
    {
        // now process submission  

        HtmlElement parentForm = null;

        /////////////////
        // parse dom to find the form you're looking for 
        // couple of helpers below
        ///////////////////////

        parentForm = HtmlElementQuery(_browser.Document, "myTextFieldInput");

        var sub = (_browser.Tag as Submission);

        HtmlDocument doc = _browser.Document;

        if (parentForm != null)
        {               
            var elements = parentForm.GetElementsByTagName("input");
            foreach (HtmlElement el in elements)
            {
                // If there's more than one button, you can check the
                // element.InnerHTML to see if it's the one you want
                if (el.GetAttribute("type").ToLower() == "submit")
                {
                    var cts = new CancellationTokenSource(Properties.Settings.Default.BrowserNavigationTimeout); // cancel in 10s

                    var html = await RaiseDynamicEvent(el, "click", cts.Token);
                }
            }
        }
    }

      // used to raise an event with a dom element that would cause the document to change 
    async Task<string> RaiseDynamicEvent(HtmlElement element, string evt, CancellationToken token)
    {
        // navigate and await DocumentCompleted
        var tcs = new TaskCompletionSource<bool>();
        WebBrowserDocumentCompletedEventHandler handler = (s, arg) =>
            tcs.TrySetResult(true);
        _browserTasks[_browser] = tcs;
        using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: true))
        {
            this._browser.DocumentCompleted += handler;

            try
            {
                element.InvokeMember(evt);
                try
                {
                    await tcs.Task; // wait for DocumentCompleted
                }
                catch (TaskCanceledException)
                {
                    // no the end of the world

                }
            }
            finally
            {
                this._browser.DocumentCompleted -= handler;
            }
        }

        // get the root element
        var documentElement = this._browser.Document.GetElementsByTagName("html")[0];

        // poll the current HTML for changes asynchronosly
        var html = documentElement.OuterHtml;
        while (true)
        {
            // wait asynchronously, this will throw if cancellation requested
            await Task.Delay(500, token);

            // continue polling if the WebBrowser is still busy
            if (this._browser.IsBusy)
                continue;

            var htmlNow = documentElement.OuterHtml;
            if (html == htmlNow)
                break; // no changes detected, end the poll loop

            html = htmlNow;
        }

        // consider the page fully rendered 
        token.ThrowIfCancellationRequested();

        // remove from task dictionary
        _browserTasks[this._browser] = null;

        return html;
    }

    // couple of useful helpers

    HtmlElement FindParentByElement(string elementName, HtmlElement element)
    {
        if (element.Parent != null)
        {
            if (element.Parent.TagName.ToLower() == elementName.ToLower())
            {
                return element.Parent;
            }
            else
            {
                return FindParentByElement(elementName, element.Parent);
            }
        }
        else
        {
            return null;
        }
    }

    HtmlElement HtmlElementQuery(HtmlDocument container, string query)
    {
        HtmlElement el = null;
        if (query.StartsWith("#"))
        {
            el = container.GetElementById(query.TrimStart('#'));
        }
        else
        {
            el = container.All[query];
        }

        return el;
    }
//_profileQueue是我想要导航并查找
///表单元素并“单击”上的提交按钮
私有异步void Next()
{
提交res=null;
if(_profileQueue.TryDequeue(out res))
{
//脏,但在标记中保留我导航到的url的详细信息
_Tag=res;
var cts=new CancellationTokenSource(Properties.Settings.Default.BrowserNavigationTimeout);//10秒后取消
var html=await LoadDynamicPage(res.SiteProfile.URL,cts.Token);
//这将在加载后解析dom(等待页面)
ProcessSiteProfile();
Next();
}
}
//导航和下载
异步任务LoadDynamicPage(字符串url、CancellationToken令牌)
{
//导航并等待文档完成
var tcs=new TaskCompletionSource();
WebBrowserDocumentCompletedEventHandler=(s,arg)=>
tcs.TrySetResult(真);
//我将tcs保存在针对浏览器对象的concurrentdictionary中
//同样,这是相当肮脏,但显然感觉我需要它。
_浏览器任务[_browser]=tcs;
使用(token.Register(()=>tcs.trysetconceled(),useSynchronizationContext:true))
{
//导航到页面异步
此._browser.DocumentCompleted+=处理程序;
尝试
{
如果(!string.IsNullOrWhiteSpace(url))
{
此._浏览器.导航(url);
wait tcs.Task;//等待文档完成
}
}
最后
{
此._browser.DocumentCompleted-=处理程序;
}
}
//获取根元素
var documentElement=this.\u browser.Document.GetElementsByTagName(“html”)[0];
//异步轮询当前HTML的更改
var html=documentElement.OuterHtml;
while(true)
{
//异步等待,如果请求取消,则将抛出
等待任务。延迟(Properties.Settings.Default.BrowserNavigationWait,令牌);
//如果WebBrowser仍然忙,请继续轮询
如果(此.\u browser.IsBusy)
继续;
var htmlNow=documentElement.OuterHtml;
如果(html==htmlNow)
break;//未检测到任何更改,结束轮询循环
html=htmlNow;
}
//考虑页面完全呈现
token.ThrowIfCancellationRequested();
//从任务字典中删除
_browserTasks[此浏览器]=空;
返回html;
}
异步void ProcessSiteProfile()
{
//现在处理提交
HtmlElement parentForm=null;
/////////////////
//解析dom以查找要查找的表单
//下面有几个助手
///////////////////////
parentForm=HtmlElementQuery(_browser.Document,“myTextFieldInput”);
var sub=(_browser.Tag作为提交);
HtmlDocument doc=\u browser.Document;
if(parentForm!=null)
{               
var elements=parentForm.GetElementsByTagName(“输入”);
foreach(元素中的HtmlElement el)
{
//如果有多个按钮,您可以检查
//element.InnerHTML查看它是否是您想要的
if(el.GetAttribute(“type”).ToLower()=“提交”)
{
var cts=new CancellationTokenSource(Properties.Settings.Default.BrowserNavigationTimeout);//10秒后取消
var html=await RaiseDynamicEvent(el,“click”,cts.Token);
}
}
}
}
//用于引发具有dom元素的事件,该事件将导致文档更改
异步任务RaiseDynamicEvent(HtmleElement元素、字符串evt、CancellationToken标记)
{
//导航并等待文档完成
var tcs=new TaskCompletionSource();
WebBrowserDocumentCompletedEventHandler=(s,arg)=>
tcs.TrySetResult(真);
_浏览器任务[_browser]=tcs;
使用(token.Register(()=>tcs.trysetconceled(),useSynchronizationContext:true))
{
此._browser.DocumentCompleted+=处理程序;
尝试
{
元素调用成员(evt);
尝试
{
wait tcs.Task;//等待文档完成
}
捕获(TaskCanceledException)
{
//不,世界末日
}
}
最后
{
此._browser.DocumentCompleted-=处理程序;
}
}
//获取根元素
var documentElement=this.\u browser.Document.GetElementsByTagName(“html”)[0];
//轮询当前HTML f