Troubleshooting HTTPClient asynchronous POST and r

2019-06-08 12:45发布

问题:

I have a problem post string to form and read. Problem is they get away but need to do so sophisticated and it was very fast. Absolutely perfect multithreaded or asynchronous. Thank you very for your help. This is my code.

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();
        }
    }

回答1:

Taking a rough stab in the dark at what your problem is, I'd guess that you're having trouble reading the response of your call.

When the content is POSTed to the server,

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();
    } 

It does so asynchronously, so the code will continue execution even though the result is not (most likely) available yet. Checking response.IsSuccessStatusCode will thus not give you the behavior you're expecting.

Change your calls to look like this by adding the await keyword:

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

Then, change the reading of the stream to use await as well:

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

EDIT: got some await objects mixed up and have corrected the code listing.

edit 2: here is the complete LINQPad script that I used to successfully download an HTML page from the given URL.

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
}


回答2:

Maybe the site has changed since last post but now the request parameter name is whois not text. If this was the case a year ago too that's why it didn't work.

Today site responds to get too, i.e. http://whois.sk-nic.sk/index.jsp?whois=PREM-0001

Full code with get:

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;
    }
}

Full code with post:

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;
    }
}

Or a parser could be used because I guess extracting the returned values is the final goal:

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();
}