HttpClient GetAsync с хешем в URL - PullRequest
0 голосов
/ 03 января 2019

Консольное приложение .NET Core 2.2 в Windows.

Я изучаю, как использовать HttpClient GetAsync для URL-адреса стиля общего ресурса Stackoverflow, например: https://stackoverflow.com/a/29809054/26086, который возвращает URL-адрес перенаправления 302 с хешем

static async Task Main()
{
    var client = new HttpClient();

    // 1. Doesn't work - has a hash in URL
    var url = "https://stackoverflow.com/questions/29808915/why-use-async-await-all-the-way-down/29809054#29809054";
    HttpResponseMessage rm = await client.GetAsync(url);
    Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 400 Bad Request

    // 2. Does work - no hash
    url = "https://stackoverflow.com/questions/29808915/why-use-async-await-all-the-way-down/29809054";
    rm = await client.GetAsync(url);
    Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 200 Okay

    // 3. Doesn't work as the 302 redirect goes to the first URL above with a hash
    url = "https://stackoverflow.com/a/29809054/26086";
    rm = await client.GetAsync(url);
    Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 400 Bad Request
}

Я сканирую свой блог, в котором содержится так много коротких кодов.

Обновление / Обходной путь Благодаря @rohancragg я обнаружил, что отключение AutoRedirect и получение URI из возвращенного заголовка работает

// as some autoredirects fail due to #fragments in url, handle redirects manually
var handler = new HttpClientHandler { AllowAutoRedirect = false };
var client = new HttpClient(handler);

var url = "https://stackoverflow.com/a/29809054/26086";    
HttpResponseMessage rm = await client.GetAsync(url);

// gives the desired new URL which can then GetAsync
Uri u = rm.Headers.Location;

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Как подразумевает @Damien_The_Unbeliever в комментарии, вам просто нужно убрать хеш и все после него - все, что нужно, это сказать браузеру перейти к этому тегу привязки на странице HTML (см .: https://w3schools.com/jsref/prop_anchor_hash.asp).

Вы также можете использовать класс Uri для анализа Uri и игнорирования любых «фрагментов»: https://docs.microsoft.com/en-us/dotnet/api/system.uri.fragment

Поскольку URL-адреса в стиле общего ресурса будут возвращать только 302, я бы предложил захватить Uri, на который ссылается 302, и сделать то, что я предлагаю выше, и просто получить путь и проигнорировать фрагмент.

Так что вам нужно использовать какой-то механизм (который я просто смотрю!), Чтобы изящно обработать 302, за которым следует опция 2

Обновление: это выглядит актуально! Как заставить System.Net.Http.HttpClient не выполнять перенаправления 302?

Обновление 2 У Стива Гуиди есть очень важный совет в комментарии: https://stackoverflow.com/a/17758758/5351

В ответ на совет, который вам нужно использовать HttpResponseMessage.RequestMessage.RequestUri:

очень важно добавить HttpCompletionOption.ResponseHeadersRead в качестве второго параметра вызова GetAsync()


Отказ от ответственности - я не пробовал выше, это просто на основе чтения; -)

0 голосов
/ 03 января 2019

Возможно, вам нужно закодировать ваш URL перед отправкой запроса с использованием класса HttpUtility, таким образом, любой специальный символ будет экранирован.

using System.Web;

var url = $"htpps://myurl.com/{HttpUtility.UrlEncode("#1234567")}";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...