C# HttpClient.SendAsync всегда возвращает 404, но URL работает в браузере

Я разрабатываю консольное приложение на C# для проверки правильности URL-адреса. Это хорошо работает для большинства URL-адресов. Но мы обнаружили, что в некоторых случаях приложение всегда получало 404 ответа от целевого сайта, но URL-адреса фактически работают в браузере. И эти URL-адреса также работают, когда я пробовал их в таких инструментах, как DHC (Dev HTTP Client).

В начале я подумал, что это может быть причиной не правильного добавления заголовков. Но после попытки использовать Fiddler для составления http-запроса с теми же заголовками, он работает в Fiddler.

Так что не так с моим кодом? Есть ли какая-либо ошибка в.NET HttpClient?

Вот упрощенный код моего тестового приложения:

class Program
{
    static void Main(string[] args)
    {
        var urlTester = new UrlTester("http://www.hffa.it/short-master-programs/fashion-photography");

        Console.WriteLine("Test is started");

        Task.WhenAll(urlTester.RunTestAsync());

        Console.WriteLine("Test is stoped");
        Console.ReadKey();
    }


    public class UrlTester
    {
        private HttpClient _httpClient;
        private string _url;

        public UrlTester(string url)
        {
            _httpClient = new HttpClient 
            { 
                Timeout = TimeSpan.FromMinutes(1)
            };

            // Add headers
            _httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36");
            _httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip,deflate,sdch");
            _httpClient.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            _httpClient.DefaultRequestHeaders.Add("Accept-Language", "sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4");

            _url = url;
        }

        public async Task RunTestAsync()
        {
            var httpRequestMsg = new HttpRequestMessage(HttpMethod.Get, _url);

            try
            {
                using (var response = await _httpClient.SendAsync(httpRequestMsg, HttpCompletionOption.ResponseHeadersRead))
                {
                    Console.WriteLine("Response: {0}", response.StatusCode);
                }
            }
            catch (HttpRequestException e) 
            {
                Console.WriteLine(e.InnerException.Message);
            }
        }
    }

}

2 ответа

Решение

Это кажется проблемой с принятыми языками. Я получил 200 ответ при использовании следующего Accept-Language значение заголовка

_httpClient.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en-US;q=0.8,en;q=0.6,ru;q=0.4");

PS Я полагаю, вы знаете, в вашем примере _client должен прочесть _httpClient в конструкторе urlTester или не будет строить.

Другая возможная причина этой проблемы - если отправляемый вами URL-адрес имеет длину более 2048 байт. В этот момент содержимое (почти наверняка строка запроса) может быть усечено, а это, в свою очередь, означает, что оно может не соответствовать корректно с маршрутом на стороне сервера.

Хотя эти URL-адреса были правильно обработаны в браузере, они также не смогли выполнить команду get в Power Shell.

Эта проблема была решена путем использования POST с парами ключ-значение вместо использования GET с длинной строкой запроса.

Другие вопросы по тегам