0

I want to display a MediaWiki page in my desktop application using a .NET WebBrowser control. The wiki requires a login. The answer provided here is not acceptable for me because AutoComplete dialogs pop up when using the WebBrowser control.

My approach is to login with a System.Net.WebClient object using api.php?action=clientlogin and then use the cookie that I get to access a wiki page. I can successfully login using the API but when I load a page I'm not logged in.

The code below uses a WebClient object to load the final page. This is for testing purposes and to eliminate another source of error (changing the User-Agent for example).

How do I do this correctly? Am I approaching this wrong?

private void Login(string username, string password)
{
    string cookie, loginToken, baseUri = "https://www.mediawiki.org";
    var client = new WebClient();

    // get logintoken and cookie
    using (var stream = client.OpenRead(baseUri + "/w/api.php?action=query&meta=tokens&format=xml&type=login"))
    {
        cookie = client.ResponseHeaders[HttpResponseHeader.SetCookie].Split(';')[0];

        var document = System.Xml.Linq.XDocument.Load(stream);
        loginToken = (string)document.XPathEvaluate("string(/api/query/tokens/@logintoken)");
    }

    // login
    client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
    client.Headers[HttpRequestHeader.Cookie] = cookie;

    var response = client.UploadString(baseUri + "/w/api.php?format=xml", "action=clientlogin&username=" + username +
                                       "&password=" + password + "&loginreturnurl=" + baseUri +
                                       "&logintoken=" + Uri.EscapeDataString(loginToken));

    // new cookie (???)
    cookie = client.ResponseHeaders[HttpResponseHeader.SetCookie].Split(';')[0];

    // success?
    if (response.Contains("status=\"PASS\""))
    {
        client.Headers.Clear();
        client.Headers[HttpRequestHeader.Cookie] = cookie;

        var data = client.DownloadData(baseUri + "/wiki/API:Login");
        var text = Encoding.UTF8.GetString(data); // <--- not logged in
    }
}
BenZinra
  • 270
  • 2
  • 10

1 Answers1

0

Try the following

navigate to the website in the form load event

private void Form1_Load(object sender, EventArgs e)
{
    webBrowser1.Navigate("https://www.mediawiki.org");
}

In the web browser complete event write the following code and add using System.Linq; namespace

private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (webBrowser1.Url.AbsoluteUri == "https://www.mediawiki.org/wiki/MediaWiki")
    {
        // Click the login link
        // Get a log in link by name
        HtmlElement linkElement = (from HtmlElement element in webBrowser1.Document.GetElementsByTagName("a") select element)
            .Where(x => x.InnerText != null && string.Compare(x.InnerText, "Log in", true) == 0).FirstOrDefault();
        if (linkElement != null)
        {
            linkElement.InvokeMember("click");
        }
    }
    else if (webBrowser1.Url.AbsoluteUri == "https://www.mediawiki.org/w/index.php?title=Special:UserLogin&returnto=MediaWiki")
    {
        // Get user name
        HtmlElement userNameElement = (from HtmlElement element in webBrowser1.Document.GetElementsByTagName("input") select element)
                    .Where(x => x.Id != null && string.Compare(x.Id, "wpName1", true) == 0).FirstOrDefault();

        // Get pass word
        HtmlElement passwordElement = (from HtmlElement element in webBrowser1.Document.GetElementsByTagName("input") select element)
                    .Where(x => x.Id != null && string.Compare(x.Id, "wpPassword1", true) == 0).FirstOrDefault();

        // Get login button
        HtmlElement loginElement = webBrowser1.Document.GetElementById("wpLoginAttempt");

        if (userNameElement != null && passwordElement != null && loginElement != null)
        {
          userNameElement.SetAttribute("value","User User Name");
          passwordElement.SetAttribute("value", "Password");
          loginElement.InvokeMember("click");
         }
     }
}
Golda
  • 3,823
  • 10
  • 34
  • 67