Estoy tratando de recuperar una fila específica en una solicitud json a través del método WebResponse, pero actualmente no funciona. Estoy convirtiendo un audio de archivos wav a texto. Funciona bien y lo convierte bien, pero obtengo filas de salida: RecognitionStatus, Duration, Display, Offset. La única fila que quiero superar en el cuadro de texto es la fila "Pantalla" donde se convierte el audio en texto.

El formato json se ve así y estoy tratando de obtener solo la fila "Pantalla".

{
  "RecognitionStatus": "Success",
  "Offset": 22500000,
  "Duration": 21000000,
  "NBest": [{
    "Confidence": 0.941552162,
    "Lexical": "find a funny movie to watch",
    "ITN": "find a funny movie to watch",
    "MaskedITN": "find a funny movie to watch",
    "Display": "Find a funny movie to watch."
  }]
}

Este es mi código actual hasta ahora.

        HttpWebRequest request = null;
        string ResponseString;
        request = (HttpWebRequest)HttpWebRequest.Create("https://speech.platform.bing.com/speech/recognition/dictation/cognitiveservices/v1?language=en-US&format=simple");
        request.SendChunked = true;
        request.Accept = @"application/json;text/xml";
        request.Method = "POST";
        request.ProtocolVersion = HttpVersion.Version11;
        request.ContentType = @"audio/wav; codec=audio/pcm; samplerate=16000";
        request.Headers["Ocp-Apim-Subscription-Key"] = "hidden";

        using (FileStream fs = new FileStream(@"G:\Microsoft Visual Studio Projects\SpeechRecognitionFormsTestUpdaterad\SpeechRecognitionForms\bin\Debug\Logs\log 24-2.wav", FileMode.Open, FileAccess.Read))
        {
            byte[] buffer = null;
            int bytesRead = 0;
            using (Stream requestStream = request.GetRequestStream())
            {
                /*
                * Read 1024 raw bytes from the input audio file.
                */

                buffer = new Byte[checked((uint)Math.Min(1024, (int)fs.Length))];
                while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
                {
                    requestStream.Write(buffer, 0, bytesRead);
                }

                // Flush
                requestStream.Flush();
            }
        }
        using (WebResponse response = request.GetResponse())
        {
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                ResponseString = sr.ReadToEnd();
                JavaScriptSerializer js = new JavaScriptSerializer();
                MyObject obj = (MyObject)js.Deserialize(ResponseString, typeof(MyObject));
                textBox1.Text = ResponseString;
            }
            //textBox1.Text = ResponseString;
        }
2
user9310993 24 feb. 2018 a las 17:40

4 respuestas

La mejor respuesta

Como NBest será una colección. Tendrá que iterar para obtener cada valor de Display.

Puede recuperar el valor de Display como:

using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
    ResponseString = sr.ReadToEnd();
    JavaScriptSerializer js = new JavaScriptSerializer();
    MyObject obj = (MyObject)js.Deserialize(ResponseString, typeof(MyObject));
    textBox1.Text = ResponseString;
    foreach (var nb in obj.NBest)
    {
        Console.WriteLine(nb.Display);
    }
}

O en caso de que siempre obtenga un único objeto NBest, puede recuperarlo como:

if (obj.NBest.Count == 1)
{
    string display = obj.NBest[0].Display;
}

Actualización:

Las siguientes son las clases en las que deserialicé el JSON de OP en:

public class MyObject
{
    public string RecognitionStatus { get; set; }
    public int Offset { get; set; }
    public int Duration { get; set; }
    public List<Nbest> NBest { get; set; }
}

public class Nbest
{
    public float Confidence { get; set; }
    public string Lexical { get; set; }
    public string ITN { get; set; }
    public string MaskedITN { get; set; }
    public string Display { get; set; }
}

Salida:

enter image description here

2
FaizanHussainRabbani 24 feb. 2018 a las 15:07

Como su respuesta es solo json, ¿por qué no intenta convertirlo en un objeto deserializado utilizando Método de deserialización de Newtonsoft.Json. Le dará acceso a una propiedad específica desde la respuesta. Puede usar este JsonToC # que le dará un objeto de la cadena json.

O simplemente obj.NBest[index] le dará un registro específico.

0
Harish 24 feb. 2018 a las 15:08

La respuesta de Faizan es acertada y te dará lo que quieres. Sin embargo, si no desea molestarse en crear un objeto para deserializar su respuesta. Puede utilizar la palabra clave dinámica, del mismo modo:

using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
    ResponseString = sr.ReadToEnd();
    JavaScriptSerializer js = new JavaScriptSerializer();
    dynamic obj = js.Deserialize<dynamic>(ResponseString);
    textBox1.Text = obj["NBest"][0]["Display"];
}
0
David Moreira 24 feb. 2018 a las 19:38

Sin necesidad de deserializar a tipos personalizados, puede usar objetos JSON.Net nativos:

string thejson = @"
{
  ""RecognitionStatus"": ""Success"",
  ""Offset"": 22500000,
  ""Duration"": 21000000,
  ""NBest"": [{
    ""Confidence"": 0.941552162,
    ""Lexical"": ""find a funny movie to watch"",
    ""ITN"": ""find a funny movie to watch"",
    ""MaskedITN"": ""find a funny movie to watch"",
    ""Display"": ""Find a funny movie to watch.""
  }]
}";

var jobj = JObject.Parse(thejson);
JArray arr = jobj["NBest"] as JArray;
foreach (JToken jt in arr)
{
    Console.WriteLine(jt["Display"]);
}
1
Crowcoder 24 feb. 2018 a las 15:17