¿Cómo obtener el cuerpo del contenido de una llamada httpclient?


He estado tratando de averiguar cómo leer el contenido de una llamada httpclient, y parece que no puedo entenderlo. El estado de respuesta que recibo es 200, pero no puedo averiguar cómo llegar al Json real que se devuelve, que es todo lo que necesito!

El siguiente es mi código:

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

Y lo estoy recibiendo simplemente llamándolo desde un método:

Task<string> result =  GetResponseString(text);

Y esto es lo que obtengo

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>

Actualización: Este es mi código actual según la respuesta de Nathan abajo

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

Y lo llamo desde este método....

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

Y sigue corriendo para siempre, golpea la línea var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result); Una vez, y continúa sin detenerse en otro punto de interrupción.

Cuando hago una pausa en la ejecución, dice {[7]]}

Id = No se puede evaluar la expresión porque el código del método actual está optimizado., Status = No se puede evaluar la expresión porque el código del método actual está optimizado., Method = Cannot evaluate expression because the code of the el método actual está optimizado., Result = No puede evaluar la expresión porque el código del método actual está optimizado.

.. Continúo la ejecución, pero es para siempre. No estoy seguro de cuál es el problema

Author: Cœur, 2014-10-28

2 answers

La forma en que está utilizando await/async es pobre en el mejor de los casos, y hace que sea difícil de seguir. Estás mezclando await con Task'1.Result, lo cual es confuso. Sin embargo, parece que está mirando un resultado final de la tarea, en lugar de los contenidos.

He reescrito su función y llamada a función, lo que debería solucionar su problema:

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

Y su llamada final a la función:

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

O incluso mejor:

var finalResult = await GetResponseString(text);
 110
Author: Nathan A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-27 22:40:35

Si no desea usar async puede agregar .Result para forzar la ejecución sincrónica del código:

    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;
     }  
 39
Author: nbushnell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-18 11:54:37