c# - crear cadena JSON desde SqlDataReader




asp.net database (3)

ACTUALIZAR

Me lo imaginé. Mira mi respuesta a continuación .

Estoy intentando crear una cadena JSON que represente una fila de una tabla de base de datos para devolverla en una respuesta HTTP. Parece que Json.NET sería una buena herramienta para utilizar. Sin embargo, no estoy seguro de cómo construir la cadena JSON mientras estoy leyendo desde la base de datos.

El problema está marcado por los desagradables comentarios /******** ********/

// connect to DB
theSqlConnection.Open(); // open the connection

SqlDataReader reader = sqlCommand.ExecuteReader();
if (reader.HasRows) {

    while(reader.Read()) {

        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);

        using (JsonWriter jsonWriter = new JsonTextWriter(sw)) {

            // read columns from the current row and build this JsonWriter
            jsonWriter.WriteStartObject();
            jsonWriter.WritePropertyName("FirstName");

            // I need to read the value from the database
/******** I can't just say reader[i] to get the ith column. How would I loop here to get all columns? ********/
            jsonWriter.WriteValue(... ? ...);
            jsonWriter.WritePropertyName("LastName");
            jsonWriter.WriteValue(... ? ...);
            jsonWriter.WritePropertyName("Email");
            jsonWriter.WriteValue(... ? ...);

            // etc...
            jsonWriter.WriteEndObject();
        }
    }
}

El problema es que no sé cómo leer cada columna de la fila del SqlReader poder llamar a WriteValue y darle la información correcta y adjuntarla al nombre correcto de la columna. Entonces, si una fila se ve así ...

| FirstName | LastName | Email |

... ¿cómo crearía un JsonWriter para cada fila tal que contenga todos los nombres de columna de la fila y los valores correspondientes en cada columna y luego use ese JsonWriter para construir una cadena JSON que esté lista para regresar a través de una respuesta HTTP?

Avíseme si necesito aclarar algo.


¡Lo tengo! Aquí está el C # ...

// ... SQL connection and command set up, only querying 1 row from the table
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonWriter jsonWriter = new JsonTextWriter(sw);

try {

    theSqlConnection.Open(); // open the connection

    // read the row from the table
    SqlDataReader reader = sqlCommand.ExecuteReader();
    reader.Read();

    int fieldcount = reader.FieldCount; // count how many columns are in the row
    object[] values = new object[fieldcount]; // storage for column values
    reader.GetValues(values); // extract the values in each column

    jsonWriter.WriteStartObject();
    for (int index = 0; index < fieldcount; index++) { // iterate through all columns

        jsonWriter.WritePropertyName(reader.GetName(index)); // column name
        jsonWriter.WriteValue(values[index]); // value in column

    }
    jsonWriter.WriteEndObject();

    reader.Close();

} catch (SqlException sqlException) { // exception
    context.Response.ContentType = "text/plain";
    context.Response.Write("Connection Exception: ");
    context.Response.Write(sqlException.ToString() + "\n");
} finally {
    theSqlConnection.Close(); // close the connection
}
// END of method
// the above method returns sb and another uses it to return as HTTP Response...
StringBuilder theTicket = getInfo(context, ticketID);
context.Response.ContentType = "application/json";
context.Response.Write(theTicket);

... por lo que la variable StringBuilder sb es el objeto JSON que representa la fila que quería consultar. Aquí está el JavaScript ...

$.ajax({
    type: 'GET',
    url: 'Preview.ashx',
    data: 'ticketID=' + ticketID,
    dataType: "json",
    success: function (data) {

        // data is the JSON object the server spits out
        // do stuff with the data
    }
});

Gracias a Scott por su respuesta que me inspiró para llegar a mi solución.

Hristo


Hice el siguiente método donde convierte cualquier DataReader a JSON, pero solo para serialización de profundidad única:

debe pasar el lector y los nombres de las columnas como una matriz de cadenas, por ejemplo:

String [] columns = {"CustomerID", "CustomerName", "CustomerDOB"};

luego llama al método

public static String json_encode(IDataReader reader, String[] columns)
    {
        int length = columns.Length;

        String res = "{";

        while (reader.Read())
        {
            res += "{";

            for (int i = 0; i < length; i++)
            {
                res += "\"" + columns[i] + "\":\"" + reader[columns[i]].ToString() + "\"";

                if (i < length - 1)
                    res += ",";
            }

            res += "}";
        }

        res += "}";

        return res;
    }

Mi version:

Esto no usa DataSchema y también ajusta los resultados en una matriz, en lugar de usar un escritor por fila.

SqlDataReader rdr = cmd.ExecuteReader();

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);    

using (JsonWriter jsonWriter = new JsonTextWriter(sw)) 
{    
    jsonWriter.WriteStartArray();

    while (rdr.Read())
    {
        jsonWriter.WriteStartObject();

        int fields = rdr.FieldCount;

        for (int i = 0; i < fields; i++)
        { 
            jsonWriter.WritePropertyName(rdr.GetName(i));
            jsonWriter.WriteValue(rdr[i]);
        }

        jsonWriter.WriteEndObject();
    }

    jsonWriter.WriteEndArray();
}




json.net