web-dev-qa-db-fra.com

Comment obtenir le corps du contenu d'un appel httpclient?

J'ai essayé de comprendre comment lire le contenu d'un appel httpclient, et je n'arrive pas à l'obtenir. Le statut de réponse que je reçois est 200, mais je ne vois pas comment obtenir le Json retourné, ce qui est tout ce dont j'ai besoin!

Voici mon code:

async Task<string> GetResponseString(string text)
{
    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;
    Task<HttpResponseMessage> response = 
        httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));

    return await response.Result.Content.ReadAsStringAsync();
}

Et je l'obtiens juste en l'appelant d'une méthode:

Task<string> result =  GetResponseString(text);

Et c'est ce que je reçois

response Id = 89, Status = RanToCompletion, Method = "{null}", Result = "StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n Connection: keep-alive\r\n Date: Mon, 27 Oct 2014 21:56:43 GMT\r\n ETag: \"5a266b16b9dccea99d3e76bf8c1253e0\"\r\n Server: nginx/0.7.65\r\n Content-Length: 125\r\n Content-Type: application/json\r\n}" System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>

Mise à jour: Ceci est mon code actuel selon la réponse de Nathan ci-dessous

    async Task<string> GetResponseString(string text)
    {
        var httpClient = new HttpClient();

        var parameters = new Dictionary<string, string>();
        parameters["text"] = text;

        var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));
        var contents = await response.Content.ReadAsStringAsync();

        return contents;
    }

Et je l'appelle de cette méthode ....

 string AnalyzeSingle(string text)
    {
        try
        {
            Task<string> result = GetResponseString(text);
            var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result);

            if (Convert.ToInt16(model.pos) == 1)
            {
                _numRetries = 0;
                return "positive";
            }

            if (Convert.ToInt16(model.neg) == 1)
            {
                _numRetries = 0;
                return "negative";
            }

            if (Convert.ToInt16(model.mid) == 1)
            {
                _numRetries = 0;
                return "neutral";
            }

            return "";
        }
        catch (Exception e)
        {
            if (_numRetries > 3)
            {
                LogThis(string.Format("Exception caught [{0}] .... skipping", e.Message));
                _numRetries = 0;
                return "";
            }
            _numRetries++;
            return AnalyzeSingle(text);
        }
    }

Et il continue à fonctionner pour toujours, il frappe la ligne var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result); une fois, et il continue à fonctionner sans s'arrêter à un autre point d'arrêt.

Quand je suspends l'exécution, ça dit

Id = Impossible d'évaluer une expression car le code de la méthode actuelle est optimisé., Status = Impossible d'évaluer une expression car le code de la méthode actuelle est optimisé., Méthode = Impossible d'évaluer une expression car le code de la méthode actuelle est optimisé., Résultat = Impossible d'évaluer une expression car le code de la méthode actuelle est optimisé.

.. Je continue l'exécution, mais ça fonctionne pour toujours. Je ne sais pas quel est le problème

80
Sherman Szeto

La façon dont vous utilisez wait/async est au mieux médiocre et rend difficile à suivre. Vous mélangez await avec Task'1.Result, ce qui prête à confusion. Cependant, il semble que vous examiniez le résultat final d'une tâche plutôt que son contenu.

J'ai réécrit votre fonction et votre appel de fonction, ce qui devrait résoudre votre problème:

async Task<string> GetResponseString(string text)
{
    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;

    var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters));
    var contents = await response.Content.ReadAsStringAsync();

    return contents;
}

Et votre dernier appel de fonction:

Task<string> result = GetResponseString(text);
var finalResult = result.Result;

Ou même mieux:

var finalResult = await GetResponseString(text);
145
Nathan A

Si vous ne souhaitez pas utiliser async, vous pouvez ajouter .Result pour forcer le code à s'exécuter de manière synchrone:

private string GetResponseString(string text)
{
    var httpClient = new HttpClient();

    var parameters = new Dictionary<string, string>();
    parameters["text"] = text;

    var response = httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)).Result;
    var contents = response.Content.ReadAsStringAsync().Result;

    return contents;
 }  
49
nbushnell