De DataTable en C # .NET vers JSON

Je suis assez nouveau en C # et en .NET, mais j’ai créé ce code pour appeler une procédure stockée et je souhaite ensuite extraire le DataTable renvoyé et le convertir en JSON.

SqlConnection con = new SqlConnection("connection ssortingng 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); } 

Ma question est alors quel est le meilleur / moyen le plus simple de le faire? Un exemple serait formidable car je suis encore très novice dans ce domaine.

Au lieu d’un datatable, vous devriez utiliser un datareader. Votre code est inefficace et un peu difficile à lire – vous pouvez vouloir faire quelque chose comme ceci:

 SsortingngBuilder json = new SsortingngBuilder(); using(SqlConnection cnn = new SqlConnection(your_connection_ssortingng)) { 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(); } 

vous pouvez ensuite utiliser json.ToSsortingng pour obtenir le résultat

Bien que JavaScriptSerializer (System.Web.Script.Serialization.JavaScriptSerializer) ne puisse pas convertir un DataTable directement en JSON, il est possible de décompresser un DataTable dans une liste pouvant ensuite être sérialisée.

La fonction suivante convertit un DataTable arbitraire en une chaîne JSON (sans connaissance préalable des noms de champ ou des types de données):

 public static ssortingng DataTableToJSON(DataTable table) { var list = new List>(); foreach (DataRow row in table.Rows) { var dict = new Dictionary(); foreach (DataColumn col in table.Columns) { dict[col.ColumnName] = row[col]; } list.Add(dict); } JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(list); } 

Vous pouvez utiliser la bibliothèque JSON.NET: http://json.codeplex.com/ pour sérialiser / désérialiser le DataTable.

 ssortingng json = JsonConvert.SerializeObject(table); 

ce qui sérial à quelque chose comme ça:

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

Si vous devez sérialiser davantage d’informations sur le DataTable, par exemple le schéma de colonnes, la clé primaire, le nom de la table, vous pouvez utiliser le convertisseur personnalisé que j’ai écrit: https://github.com/chris-herring/DataTableConverter . Utilisez-le comme ceci:

 ssortingng json = JsonConvert.SerializeObject(table, new Serialization.DataTableConverter()); DataTable table = JsonConvert.DeserializeObject(json, new Serialization.DataTableConverter()); 

ce qui sérial à quelque chose comme ça:

 { "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"] } 

Merci Ariel. Votre réponse a été très utile. Voici une version qui s’appuie sur votre réponse.

 public ssortingng ReadToJson(SqlDataReader reader) { List cols = new List(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(); } 

Merci Karl Wenzel. J’ai eu un problème où je ne pouvais recevoir qu’une table de données d’un ancien service Web asmx. Maintenant, j’ai écrit une page Web qui peut parsingr ce DataTable et le renvoyer en JSON.

 public static ssortingng DataTableToJSON(DataTable table) { List> list = new List>(); foreach (DataRow row in table.Rows) { Dictionary dict = new Dictionary(); foreach (DataColumn col in table.Columns) { dict[col.ColumnName] = row[col]; } list.Add(dict); } JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(list); } 

Une autre manière sans utiliser le sérialiseur javascript:

 public static ssortingng DataTableToJSON(DataTable Dt) { ssortingng[] StrDc = new ssortingng[Dt.Columns.Count]; ssortingng HeadStr = ssortingng.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 SsortingpControlChars(Sb.ToSsortingng()); } //Function to ssortingp control characters: //A character that does not represent a printable character but serves to initiate a particular action. public static ssortingng SsortingpControlChars(ssortingng s) { return Regex.Replace(s, @"[^\x20-\x7F]", ""); } 

J’utilise JavaScriptSerializer + LINQ

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