Flurl PostUrlEncoded делает GET вместо POST - PullRequest
0 голосов
/ 10 сентября 2018

Я, должно быть, упускаю что-то очень очевидное, но я не могу сказать, что. У меня DoLoginAsync вот так:

private async Task DoLoginAsync(bool force = false)
        {
            try
            {
                if (client.Cookies.ContainsKey("user_credentials") && !force)
                {
                    return;
                }
                var html = client.Request("login").GetStringAsync().Result;
                var doc = new HtmlDocument();
                doc.LoadHtml(html);
                var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
                var values = new Dictionary<string, string>
                {
                    { "user_session[email]", user },
                    { "user_session[password]", password },
                    { "authenticity_token", csrf_token }
                };
                var result = await client.Request("user_session").PostUrlEncodedAsync(values);
            }
            catch (Exception e)
            {
            }

Когда я запускаю этот код в тесте с точкой останова в предложении catch, я получаю исключение

Call failed with status code 404 (Not Found): GET http://www.whatever.com/user_session

WTF? Я ожидаю, что PostUrlEncodedAsync сделает POST, а не GET. У кого-нибудь есть идея, почему это может произойти?

Клиент Flurl создается как client = new FlurlClient(BASE_URL).EnableCookies();

UPDATE

Попробовал следующий тест, который не прошел с тем же исключением

[TestMethod]
        public async Task TheTest()
        {
            var message = "";
            try
            {
                var client = new FlurlClient("http://www.slimmemeterportal.nl/").EnableCookies();
                var html = await client.Request("login").GetStringAsync();
                var doc = new HtmlDocument();
                doc.LoadHtml(html);
                var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
                var values = new Dictionary<string, string>
                {
                    { "user_session[email]", "******" },
                    { "user_session[password]", "******" },
                    { "commit", "inloggen" }, // Not sure if this is actually needed, but it is in the website's request parameters.
                    { "authenticity_token", csrf_token }
                };
                var result = await client.Request("user_session").PostUrlEncodedAsync(values);
            }
            catch (FlurlHttpException ex)
            {
                message = ex.Message;
            }
            Assert.AreEqual("Call failed with status code 404 (Not Found): POST http://www.slimmemeterportal.nl/user_session", message);
        }

1 Ответ

0 голосов
/ 10 сентября 2018

Загадка решена: как выяснилось после некоторой отладки в Wireshark, веб-сайт возвращал код состояния HTTP 301. Как объяснено здесь действие по умолчанию состоит в том, чтобы следовать URI в заголовке местоположения ответа с помощью GET даже если исходный запрос был POST.

...