convertir de SqlDataReader a JSON

public string toJSON(SqlDataReader o) { StringBuilder s = new StringBuilder(); s.Append("["); if (o.HasRows) while (o.Read()) s.Append("{" + '"' + "Id" + '"' + ":" + o["Id"] + ", " + '"' + "CN" + '"' + ":" + o["CatName"] + ", " + '"' + "Ord" + '"' + ":" + o["Ord"] + "," + '"' + "Icon" + '"' + ":" + o["Icon"] + "}, "); s.Remove(s.Length - 2, 2); s.Append("]"); o.Close(); return s.ToString(); } 

Estoy usando aquí mi propia función para hacer serialización. Necesito saber si esta es una buena manera o debería usar otra. Por cierto, he tratado de usar JavaScriptSerializer pero esto no funcionó con SqlDataReader. gracias

Si quiere algo que se convierta en JSON arbitrario, puede convertirlo serializando en un diccionario (de cadena, objeto) así:

 public IEnumerable> Serialize(SqlDataReader reader) { var results = new List>(); var cols = new List(); for (var i = 0; i < reader.FieldCount; i++) cols.Add(reader.GetName(i)); while (reader.Read()) results.Add(SerializeRow(cols, reader)); return results; } private Dictionary SerializeRow(IEnumerable cols, SqlDataReader reader) { var result = new Dictionary(); foreach (var col in cols) result.Add(col, reader[col]); return result; } 

Y luego use el objeto NewtonSoft.Json JsonConvert para obtener su JSON:

 var r = Serialize(reader); string json = JsonConvert.SerializeObject(r, Formatting.Indented); 

ACTUALIZACIÓN: si solo quiere usar métodos integrados, y está usando MVC, puede usar el método de ayuda Json incorporado en su recién serializado:

 JsonResult Index(int id) { var r = Serialize(reader); return Json(r, JsonRequestBehavior.AllowGet); } 

Otra opción sería utilizar la excelente biblioteca JSON.NET de James Newton-King – http://www.newtonsoft.com/json

Aquí hay un ejemplo rápido sobre cómo usarlo para crear una colección y luego mostrarla como una cadena serializada JSON:

 using Newtonsoft.Json; class Program { static void Main(string[] args) { ArrayList objs = new ArrayList(); //get the data reader, etc. while(o.Read()) { objs.Add(new { Id = o["Id"], CN = o["CatName"], Ord = o["Ord"], Icon = o["Icon"] }); } //clean up datareader Console.WriteLine(JsonConvert.SerializeObject(objs)); Console.ReadLine(); } } 

Usted podría hacer lo mismo con su bucle leyendo en cada fila de su SqlDataReader en un objeto anónimo y luego usar JSON.NET para serializarlo en una cadena.

¡Espero que esto ayude!

Me encuentro con casos de uso en los que el número de filas que devuelve el lector de datos puede ser problemático con respecto al consumo de memoria. El siguiente código usa un JsonWriter (de JSON.NET) sobre una secuencia. Uno puede discutir la utilidad de los enormes documentos JSON, pero a veces nuestros casos de uso son dictados por otros 🙂

Algunas notas:

  • My SqlDataReader puede contener varios conjuntos de resultados (‘tablas’)
  • Es posible que esté enviando el resultado a una secuencia de FileStream o HttpResponse
  • He ‘abstraído’ mis nombres de objeto para que coincidan con la primera columna devuelta por conjunto de resultados
  • Debido al potencial de grandes conjuntos de resultados, utilizo métodos asincrónicos de SqlDataReader.
  • Dejaré que JSON.NET maneje todo el problema de serialización de los datos reales contenidos en los resultados del lector de datos.

El código:

 var stream = ... // In my case, a FileStream or HttpResponse stream using (var writer = new JsonTextWriter(new StreamWriter(stream))) { writer.WriteStartObject(); do { int row = 0; string firstColumn = null; while (await reader.ReadAsync()) { if (row++ == 0) { firstColumn = reader.GetName(0); writer.WritePropertyName(string.Format("{0}Collection", firstColumn)); writer.WriteStartArray(); } writer.WriteStartObject(); for (int i = 0; i < reader.FieldCount; i++) { if (!reader.IsDBNull(i)) { writer.WritePropertyName(reader.GetName(i)); writer.WriteValue(reader.GetValue(i)); } } writer.WriteEndObject(); } writer.WriteEndArray(); } while (await reader.NextResultAsync()); writer.WriteEndObject(); } 

Un ejemplo de salida heterogénea sería:

 { "ContactCollection": { "ContactItem": [{ "ContactID": "1", "Contact": "Testing", }, { "ContactID": "2", "Contact": "Smith, John", }, { "ContactID": "4", "Contact": "Smith, Jane", } ], "MessageItem": [{ "MessageID": "56563", "Message": "Contract Review Changed", }, { "MessageID": "56564", "Message": " Changed", }, { "MessageID": "56565", "Message": "Contract Review - Estimated Completion Added.", } ] } } 

Referencia:

Prueba esto:

 o = cmd.ExecuteReader(); var dataQuery = from d in o.Cast() select new { Id = (String)d["Id"], CN = (String)d["CatName"], Ord = (String)d["Ord"], Icon = (String)d["Icon"] }; var data = dataQuery.ToArray(); JavaScriptSerializer serializer = new JavaScriptSerializer(); String jsonData = serializer.Serialize(data); 

Esto debería hacer el trabajo

 private String sqlDatoToJson(SqlDataReader dataReader) { var dataTable = new DataTable(); dataTable.Load(dataReader); string JSONString = string.Empty; JSONString = JsonConvert.SerializeObject(dataTable); return JSONString; } 

Uso este código, basado en la respuesta de Jonathan :

 private IEnumerable> ConvertToDictionary(IDataReader reader) { var columns = new List(); var rows = new List>(); for (var i = 0; i < reader.FieldCount; i++) { columns.Add(reader.GetName(i)); } while (reader.Read()) { rows.Add(columns.ToDictionary(column => column, column => reader[column])); } return rows; } 

Y entonces:

 var rows = this.ConvertToDictionary(reader); return JsonConvert.SerializeObject(rows, Formatting.Indented); 

Esto no puede ser tan difícil. Esto es lo que hice cuando quiero devolver resultados de búsqueda a una página web como JSON.

Primero, tenga una clase como esta

 public class SearchResult { public string model_no { get; set; } public string result_text { get; set; } public string url { get; set; } public string image_url { get; set; } } 

y luego tiene el código a continuación.

  string sql_text = "select * from product_master where model_no like @search_string and active=1"; SqlConnection connection = new SqlConnection(sql_constr); SqlCommand cmd = new SqlCommand(sql_text, connection); cmd.Parameters.AddWithValue("@search_string", "%" + search_string + "%"); connection.Open(); SqlDataReader rdr = cmd.ExecuteReader(); List searchresults = new List(); while (rdr.Read()) { SearchResult sr = new SearchResult(); sr.model_no = rdr["model_no"].ToString(); sr.result_text = rdr["product_name"].ToString(); sr.url = rdr["url_key"].ToString(); searchresults.Add(sr); } connection.Close(); //build json result return Json(searchresults, JsonRequestBehavior.AllowGet); 

esto me funciona muy bien …

Esto es para mejorar la respuesta de Linq de Chandu que usa syntax de consulta (de … seleccionar …). Si prefiere la syntax del método, esta es su respuesta.

 drdr = cmd.ExecuteReader(); Record[] recs = drdr.Cast().Select( data=>new Record{ GraphID=(drdr.IsDBNull(0) ? "" : (string)data["LabelX"]) , XAxis=(drdr.IsDBNull(1) ? "1999-09-09 00:00:00" : Convert.ToDateTime(data["XDate"]).ToString("yyyy-MM-dd HH:mm:ss")) , YVal=(drdr.IsDBNull(2) ? 0 : int.Parse(data["YFreq"].ToString())) }).ToArray(); MemoryStream mem = new MemoryStream(); DataContractJsonSerializer szr = new DataContractJsonSerializer(typeof(Record[])); szr.WriteObject(mem, recs); String jsonData = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length); 

Espero que ayude a alguien.

Además de la respuesta de Jonathan , tenía un requisito similar en ASP.NET Core para convertir el resultado de un SQLDataReader a una cadena JSON o un Objeto Result, así que creé un método de extensión para él como:

  public static class MyExtensions { public async static Task toJSON(this SqlDataReader reader) { var results = await reader.GetSerialized(); return JsonConvert.SerializeObject(results, Formatting.Indented); } public async static Task>> GetSerialized(this SqlDataReader reader) { var results = new List>(); var cols = new List(); for (var i = 0; i < reader.FieldCount; i++) cols.Add(reader.GetName(i)); while (await reader.ReadAsync()) results.Add(SerializeRow(cols, reader)); return results; } private static Dictionary SerializeRow(IEnumerable cols, SqlDataReader reader) { var result = new Dictionary(); foreach (var col in cols) result.Add(col, reader[col]); return result; } } 

y lo usé según mi requisito como:

 var result = await reader.GetSerialized(); //to get the result object 

o

 string strResult = await reader.toJSON(); //to get the result string 

Creé un método asíncrono porque tenía otras cosas que hacer hasta que la lectura finalizara desde la base de datos.

Desde SQL Server 2016, Microsoft incrustó esta característica con consultas SQL. Puede lograrlo utilizando la palabra clave FOR JSON al final de sus consultas.

 select * from table_example where somecolumn = somecondition FOR JSON AUTO 

para obtener más detalles y ejemplos, puede acceder a estos documentos oficiales Formatear salida JSON automáticamente con el modo AUTO (SQL Server)

Aquí está el ejemplo del código C # de Microsoft para obtener cadena JSON de las consultas SQL.

 var queryWithForJson = "SELECT ... FOR JSON"; var conn = new SqlConnection(""); var cmd = new SqlCommand(queryWithForJson, conn); conn.Open(); var jsonResult = new StringBuilder(); var reader = cmd.ExecuteReader(); if (!reader.HasRows) { jsonResult.Append("[]"); } else { while (reader.Read()) { jsonResult.Append(reader.GetValue(0).ToString()); } } 

Advertencia: esta solución solo es válida para SQL SERVER 2016 y superior.

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

agregar referencia: System.Web.Extensions para proyectar luego

 using System.Web.Script.Serialization; 

en código c #, puede usar escribir:

  var json = new JavaScriptSerializer().Serialize(obj); 

Con Cinchoo ETL – una biblioteca de código abierto, puede exportar SqlDataReader a JSON fácilmente con pocas líneas de código

 string connectionstring = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True"; StringBuilder sb = new StringBuilder(); using (var conn = new SqlConnection(connectionstring)) { conn.Open(); var comm = new SqlCommand("SELECT top 2 * FROM Customers", conn); using (var parser = new ChoJSONWriter(sb)) parser.Write(comm.ExecuteReader()); } Console.WriteLine(sb.ToString()); 

Salida:

 [ { "CustomerID": "ALFKI", "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "ContactTitle": "Sales Representative", "Address": "Obere Str. 57", "City": "Berlin", "Region": {}, "PostalCode": "12209", "Country": "Germany", "Phone": "030-0074321", "Fax": "030-0076545" }, { "CustomerID": "ANATR", "CompanyName": "Ana Trujillo Emparedados y helados", "ContactName": "Ana Trujillo", "ContactTitle": "Owner", "Address": "Avda. de la Constitución 2222", "City": "México DF", "Region": {}, "PostalCode": "05021", "Country": "Mexico", "Phone": "(5) 555-4729", "Fax": "(5) 555-3745" } ]