HTTPClient异步POST和读取结果的故障排除

时间:2013-04-01 15:16:20

标签: c# post asynchronous httpwebrequest webclient

我有一个问题是发布字符串以形成和阅读。问题是他们逃之夭夭,但需要这么复杂,而且速度非常快。绝对完美的多线程或异步。非常感谢你的帮助。 这是我的代码。

private static void AsyncDown()
    {
        const string url = "http://whois.sk-nic.sk/index.jsp";
        const string req = "PREM-0001";
        var client = new HttpClient();

        var pairs = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("text", "PREM-0001")
        };

        FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);

        HttpResponseMessage response = client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;

        if (response.IsSuccessStatusCode)
        {

            HttpContent stream = response.Content;
            Task<string> data = stream.ReadAsStringAsync();
        }
    }

2 个答案:

答案 0 :(得分:0)

在黑暗中粗略地抓住你的问题,我猜你在阅读你的电话响应时遇到了麻烦。

当内容张贴到服务器时,

HttpResponseMessage response 
    = client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;

    if (response.IsSuccessStatusCode)
    {

        HttpContent stream = response.Content;
        Task<string> data = stream.ReadAsStringAsync();
    } 

它是异步执行的,因此代码将继续执行,即使结果(最有可能)尚未可用。因此,检查response.IsSuccessStatusCode将不会为您提供您期望的行为。

通过添加 await 关键字将您的通话更改为:

HttpResponseMessage response 
    = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);

然后,更改流的读数以使用等待:

    if (response.IsSuccessStatusCode)
    {
        var data = await response.Content.ReadAsStringAsync();
    }

编辑:得到一些等待对象混淆并纠正了代码清单。

编辑2:这是我用来从给定URL成功下载HTML页面的完整LINQPad脚本。

var client = new HttpClient();

var pairs = new List<KeyValuePair<string, string>>
{
    new KeyValuePair<string, string>("text", "PREM-0001")
};

FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);
HttpResponseMessage response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);

if (response.IsSuccessStatusCode)
{
    var data = await response.Content.ReadAsStringAsync();
    //data.Dump(); //uncomment previous if using LINQPad
}

答案 1 :(得分:0)

自上次发布以来,网站可能已更改,但现在请求参数名称不是文本。如果一年前就是这种情况,那就是它无效的原因。

今天网站也会响应,即http://whois.sk-nic.sk/index.jsp?whois=PREM-0001

获取完整代码:

private async Task<string> Get(string code)
{
    using (var client = new HttpClient())
    {
        var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);

        var data = await client.GetStringAsync(requestUri);

        return data;
    }
}

包含帖子的完整代码:

private async Task<string> Post()
{
    using (var client = new HttpClient())
    {
        var postData = new KeyValuePair<string, string>[]
        {
            new KeyValuePair<string, string>("whois", "PREM-0001"),
        };

        var content = new FormUrlEncodedContent(postData);

        var response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);

        if (!response.IsSuccessStatusCode)
        {
            var message = String.Format("Server returned HTTP error {0}: {1}.", (int)response.StatusCode, response.ReasonPhrase);
            throw new InvalidOperationException(message);
        }

        var data = await response.Content.ReadAsStringAsync();

        return data;
    }
}

或者可以使用解析器,因为我猜测提取返回的值是最终目标:

private void HtmlAgilityPack(string code)
{
    var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);

    var request = new HtmlWeb();

    var htmlDocument = request.Load(requestUri);

    var name = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[2]/td[2]").InnerText.Trim();
    var organizations = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[3]/td[2]").InnerText.Trim();
}