Como clicar em um botão em uma página da Web do ASP.NET programaticamente?

Eu estou tentando descobrir como clicar em um botão em uma página da web por meio de programação.

Especificamente, eu tenho um WinForm com um controle WebBrowser. Uma vez que ele navega para a página de login do ASP.NET de destino com a qual estou tentando trabalhar, no manipulador de eventos DocumentCompleted eu tenho o seguinte codificado:

HtmlDocument doc = webBrowser1.Document;

HtmlElement userID = doc.GetElementById("userIDTextBox");
userID.InnerText = "user1";

HtmlElement password = doc.GetElementById("userPasswordTextBox");
password.InnerText = "password";

HtmlElement button = doc.GetElementById("logonButton");
button.RaiseEvent("onclick");

Isso preenche bem as caixas de texto userid e password, mas não estou tendo nenhum sucesso em obter esse botão para clicar; Eu também tentei "clique", "Clique" e "onClick" - o que mais está lá? Uma busca de msdn, é claro, não me dá pistas, nem groups.google.com. Eu tenho que estar perto. Ou talvez não - alguém me disse que eu deveria chamar o método POST da página, mas como isso é feito não fazia parte do conselho dado.

BTW O botão está codificado:

<input type="submit" name="logonButton" value="Login" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="logonButton" tabindex="4" />
0
adicionado
Visualizações: 1
Aqui está uma boa referência para usar o controle WebBrowser (.NET 2.0) para interagir com diferentes elementos de formulário.
adicionado o autor Adam Neal, fonte

8 Respostas

Você já tentou fireEvent em vez de RaiseEvent?

0
adicionado

Você postou um comentário ao longo das linhas de não querer usar um script do lado do cliente na resposta do @Phunchak. Eu acho que o que você está tentando fazer é impossível. A única maneira de interagir com o formulário é por meio de um script do lado do cliente. O código C# só pode controlar o que acontece antes de a página ser enviada para o navegador.

0
adicionado

There is an example of how to submit the form using InvokeMember here. http://msdn.microsoft.com/en-us/library/ms171716.aspx

0
adicionado

var btn = document.getElementById (btnName); if (btn) btn.click ();

0
adicionado
Isso é ótimo se fosse o script de cliente que eu precisava, mas o que eu estou tentando fazer é o lado do servidor.
adicionado o autor Cyberherbalist, fonte

Você pode tentar invocar o método Page_ClientValidate() diretamente através do clientcript em vez de clicar no botão, deixe-me desenterrar um exemplo.

Usando o MSHTML

mshtml.IHTMLWindow2 myBroserWindow = (mshtml.IHTMLWindow2)MyWebBrowser.Document.Window.DomWindow;
myBroserWindow.execScript("Page_ClientValidate();", "javascript");
0
adicionado
Isso pode ser um problema se a página de login procurar especificamente o clique do botão
adicionado o autor Jeff Martin, fonte
É bem verdade, eu pensei sobre isso, mas decidi jogar fora o método de invocação de qualquer maneira.
adicionado o autor Quintin Robinson, fonte

Você poderia chamar o método diretamente e passar parâmetros de objeto genérico e EventArgs. É claro que isso pode não funcionar se você estiver olhando para os parâmetros sender e EventArgs para dados específicos. Como eu normalmente lidei com isso é refatorar as entranhas do método para um método doSomeAction() e o manipulador de eventos para o clique do botão simplesmente chamará essa função. Dessa forma, não preciso descobrir como invocar o que normalmente é apenas um manipulador de eventos para fazer um pouco de lógica na página/formulário.

No caso do JavaScript clicar em um botão para uma postagem de formulário, você pode invocar form.submit() no script do lado do cliente - que executará quaisquer scripts de validação que você definiu na tag - e então analisar o evento Form_Load e pegar o valor de texto do botão enviar nesse formulário (supondo que haja apenas um) - pelo menos essa é a maneira do ASP.NET 1.1 com a qual estou muito familiarizado ... alguém sabe de algo mais elegante com 2.0+?

0
adicionado

Como é que isso funciona? Funciona para mim

HtmlDocument doc = webBrowser1.Document;

doc.All["userIDTextBox"].SetAttribute("Value", "user1");
doc.All["userPasswordTextBox"].SetAttribute("Value", "Password!");
doc.All["logonButton"].InvokeMember("Click");
0
adicionado

Apenas um possível extra útil onde o botão de envio não recebeu um ID - como é frequentemente o caso.

    private HtmlElement GetInputElement(string name, HtmlDocument doc) {
            HtmlElementCollection elems = doc.GetElementsByTagName("input");

            foreach (HtmlElement elem in elems)
            {
                String nameStr = elem.GetAttribute("value");
                if (!String.IsNullOrEmpty (nameStr) && nameStr.Equals (name))
                {
                    return elem;
                }
            }
            return null;
    }

Então você pode chamar assim:

 GetInputElement("Login", webBrowser1.Document).InvokeMember("Click");

Ele gerará uma exceção se a entrada de envio com o valor 'Login', mas você puder desmembrá-la se quiser verificar condicionalmente antes de chamar o clique.

0
adicionado
Eu me senti ligeiramente impertinente e re-jigged para aceitar o documento de controle para que seja uma função genérica.
adicionado o autor MonsCamus, fonte