2010-02-22 29 views
14

Soy bastante nuevo en C# y .NET, pero hice este código para llamar a un procedimiento almacenado, y luego quiero tomar la DataTable devuelta y convertirla a JSON.De DataTable en C# .NET a JSON

SqlConnection con = new SqlConnection("connection string here"); 
    SqlDataAdapter da = new SqlDataAdapter(); 
    SqlCommand cmd = new SqlCommand("getDates", con); 
    SqlParameter par = new SqlParameter("@PlaceID", SqlDbType.Int); 
    par.Value = 42; 
    da.SelectCommand = cmd; 
    cmd.Parameters.Add(par); 
    DataSet ds = new DataSet(); 
    DataTable dt = new DataTable(); 

    con.Open(); 

    try{ 
     cmd.CommandType = CommandType.StoredProcedure; 
     da.Fill(ds); 
    } 

Mi pregunta es, entonces, ¿cuál es la mejor/más simple forma de hacerlo? Un ejemplo sería genial ya que todavía soy muy nuevo en esto.

+1

posible duplicado de [cómo convertir tabla de datos a JSON en C#] (http : //stackoverflow.com/questions/17398019/how-to-convert-datatable-to-json-inc-c-sharp) – JNF

Respuesta

7

En lugar de una tabla de datos, debe usar un lector de datos. Su código es ineficiente y algo difícil de leer - es posible que desee hacer algo como esto:

StringBuilder json = new StringBuilder(); 

using(SqlConnection cnn = new SqlConnection(your_connection_string)) 
{ 
    cnn.open(); 

    using(SqlCommand cmd = new SqlCommand("name_of_stored_procedure", cnn)) 
    { 
     cmd.Paramters.AddWithValue("@Param", "value"); 

     using(SqlDataReader reader = cmd.ExecuteReader()) 
     { 
      while(reader.Read()) 
      { 
       json.AppendFormat("{{\"name\": \"{0}\"}}", reader["name"]); 
      } 
     } 
    } 

    cnn.close(); 
} 

luego se puede utilizar para obtener el json.ToString Outpt

+0

Gracias, y gracias por la visita nt en mi código. Intentaré limpiarlo. Lo intentaré y veré qué puedo hacer con él:] – cc0

+0

y scape chars? y arreglos? no es real json: -/ –

7

Gracias Ariel. Tu respuesta fue muy útil. Aquí hay una versión que se basa en su respuesta.

public string ReadToJson(SqlDataReader reader) 
{ 
    List<string> cols = new List<string>(10); 
    int ncols = reader.FieldCount; 
    for (int i = 0; i < ncols; ++i) 
    { 
    cols.Add(reader.GetName(i)); 
    } 
    StringBuilder sbJson = new StringBuilder("["); 
    //process each row 
    while (reader.Read()) 
    { 
    sbJson.Append("{"); 
    foreach (string col in cols) 
    { 
     sbJson.AppendFormat("\"{0}\":{1}, ", col, reader[col]); 
    } 
    sbJson.Replace(", ", "},", sbJson.Length - 2, 2); 
    } 
    sbJson.Replace("},", "}]", sbJson.Length - 2, 2); 
    return sbJson.ToString(); 
} 
+0

+1 ¡Muy útil! – OammieR

+0

y scape chars ??? "\ \ n etc –

+0

@ user1243068 Esta respuesta es bastante antigua. Hoy probablemente solo inserte los contenidos de dataReader en una lista y use JSON.NET (también conocido como Newtonsoft) para convertir la lista en una matriz JSON. – Ariel

23

Aunque el JavaScriptSerializer (System.Web.Script.Serialization.JavaScriptSerializer) no puede convertir un DataTable directamente en JSON, es posible descomprimir un DataTable en una lista que puede entonces ser serializado.

La siguiente función convierte una DataTable arbitraria en una cadena JSON (sin conocimiento previo acerca de los nombres de campo o tipos de datos):

public static string DataTableToJSON(DataTable table) 
{ 
    var list = new List<Dictionary<string, object>>(); 

    foreach (DataRow row in table.Rows) 
    { 
     var dict = new Dictionary<string, object>(); 

     foreach (DataColumn col in table.Columns) 
     { 
      dict[col.ColumnName] = row[col]; 
     } 
     list.Add(dict); 
    } 
    JavaScriptSerializer serializer = new JavaScriptSerializer(); 
    return serializer.Serialize(list); 
} 
13

Se puede usar la biblioteca JSON.NET: http://json.codeplex.com/ para serializar/deserializar el DataTable .

string json = JsonConvert.SerializeObject(table); 

la que serializa a algo como esto:

[ { "Column1": "Row Value", "Column2": "2" } ] 

Si necesita más información sobre serializar DataTable por ejemplo, esquema de columna, clave principal, nombre de tabla, entonces podría usar el convertidor personalizado que escribí: https://github.com/chris-herring/DataTableConverter. Utilizar de esta manera:

string json = JsonConvert.SerializeObject(table, new Serialization.DataTableConverter()); 
DataTable table = JsonConvert.DeserializeObject<DataTable>(json, new Serialization.DataTableConverter()); 

la que serializa a algo como esto:

{ 
    "TableName": "TestTable", 
    "Columns": [ 
     { 
      "AllowDBNull": false, 
      "AutoIncrement": true, 
      "AutoIncrementSeed": 2, 
      "AutoIncrementStep": 1, 
      "Caption": "PrimaryKey", 
      "ColumnName": "PrimaryKey", 
      "DataType": "Int32", 
      "DateTimeMode": "UnspecifiedLocal", 
      "DefaultValue": null, 
      "MaxLength": -1, 
      "Ordinal": 0, 
      "ReadOnly": false, 
      "Unique": true 
     } 
    ], 
    "Rows": [ 
     [ 
      1 
     ], 
     [ 
      2 
     ], 
     [ 
      3 
     ] 
    ], 
    "PrimaryKey": ["PrimaryKey"] 
} 
+1

Waow Awesum :) +1 para dat .. –

3

Gracias Karl Wenzel. Tuve un problema donde solo podía recibir la tabla de datos de un antiguo servicio web de asmx. Ahora escribí una página web que puede analizar esta DataTable y devolverla en JSON.

public static string DataTableToJSON(DataTable table) 
{ 
    List<Dictionary<string, object>> list = new List<Dictionary<string, object>>(); 

    foreach (DataRow row in table.Rows) 
    { 
     Dictionary<string, object> dict = new Dictionary<string, object>(); 

     foreach (DataColumn col in table.Columns) 
     { 
      dict[col.ColumnName] = row[col]; 
     } 
     list.Add(dict); 
    } 
    JavaScriptSerializer serializer = new JavaScriptSerializer(); 
    return serializer.Serialize(list); 
} 
2

Una forma alternativa sin utilizar javascript serializador:

public static string DataTableToJSON(DataTable Dt) 
      { 
       string[] StrDc = new string[Dt.Columns.Count]; 

       string HeadStr = string.Empty; 
       for (int i = 0; i < Dt.Columns.Count; i++) 
       { 

        StrDc[i] = Dt.Columns[i].Caption; 
        HeadStr += "\"" + StrDc[i] + "\":\"" + StrDc[i] + i.ToString() + "¾" + "\","; 

       } 

       HeadStr = HeadStr.Substring(0, HeadStr.Length - 1); 

       StringBuilder Sb = new StringBuilder(); 

       Sb.Append("["); 

       for (int i = 0; i < Dt.Rows.Count; i++) 
       { 

        string TempStr = HeadStr; 

        for (int j = 0; j < Dt.Columns.Count; j++) 
        { 

         TempStr = TempStr.Replace(Dt.Columns[j] + j.ToString() + "¾", Dt.Rows[i][j].ToString().Trim()); 
        } 
        //Sb.AppendFormat("{{{0}}},",TempStr); 

        Sb.Append("{"+TempStr + "},"); 
       } 

       Sb = new StringBuilder(Sb.ToString().Substring(0, Sb.ToString().Length - 1)); 

       if(Sb.ToString().Length>0) 
       Sb.Append("]"); 

       return StripControlChars(Sb.ToString()); 

      } 
//Function to strip control characters: 

//A character that does not represent a printable character but serves to initiate a particular action. 

      public static string StripControlChars(string s) 
      { 
       return Regex.Replace(s, @"[^\x20-\x7F]", ""); 
      } 
2

utilizo JavaScriptSerializer + LINQ

return new JavaScriptSerializer().Serialize(
    dataTable.Rows.Cast<DataRow>() 
    .Select(row => row.Table.Columns.Cast<DataColumn>() 
    .ToDictionary(col => col.ColumnName, col => row[col.ColumnName])) 
    .ToList() 
);