带有URL中的哈希值的HttpClient GetAsync

时间:2019-01-03 15:47:41

标签: c# http url .net-core

Windows上的.NET Core 2.2控制台应用程序。

我正在探索如何在Stackoverflow共享样式URL上使用HttpClient GetAsync,例如:https://stackoverflow.com/a/29809054/26086会返回其中包含哈希的302重定向URL。

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
}

我正在抓取其中包含许多SO短代码的博客。

更新/解决方法 多亏了@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 :(得分:1)

正如@Damien_The_Unbeliever在评论中所暗示的那样,您只需要剥离散列及其后的所有内容-所做的只是告诉浏览器跳至HTML页面中的该锚标记(请参阅:{{3} }。

您还可以使用Uri类来解析Uri并忽略任何“碎片”:https://w3schools.com/jsref/prop_anchor_hash.asp

因为共享样式的Urls只会返回302,所以我建议捕获302所引用的Uri,并按照我上面的建议进行操作,只是获取路径而忽略片段。

因此,您需要使用某种机制(我只是在查找它!)来优雅地处理302和后面的选项2

更新:这看起来很有意义! https://docs.microsoft.com/en-us/dotnet/api/system.uri.fragment

更新2 在此处的评论中,史蒂夫·吉迪(Steve Guidi)有非常重要的建议:How can I get System.Net.Http.HttpClient to not follow 302 redirects?

根据您需要使用HttpResponseMessage.RequestMessage.RequestUri的建议:

  

添加HttpCompletionOption.ResponseHeadersRead非常重要   作为GetAsync()调用的第二个参数


免责声明 -我没有尝试上面的方法,这只是基于阅读;-)

答案 1 :(得分:-1)

也许您需要在使用HttpUtility类发送请求之前对URL进行编码,这样可以转义任何特殊字符。

ParentNode