Z DataTable in C#.NET do JSON

Jestem całkiem nowy w C# i. NET, ale zrobiłem ten kod, aby wywołać procedurę składowaną, a następnie chcę wziąć zwrócony DataTable i przekonwertować go do 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);
    }

Moje pytanie brzmi więc, jaki jest najlepszy / najprostszy sposób, aby to zrobić? Przykład byłby świetny, ponieważ wciąż jestem w tym nowy.

Author: cc0, 2010-02-22

7 answers

Zamiast datatable powinieneś użyć datareadera. Twój kod jest nieefektywny i nieco trudny do odczytania - możesz chcieć zrobić coś takiego:

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

Możesz następnie użyć json.ToString, Aby uzyskać outpt

 7
Author: Ariel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-22 18:16:39

Chociaż JavaScriptSerializer (System.Www.Scenariusz.Serializacja.JavaScriptSerializer) nie można przekonwertować DataTable bezpośrednio do JSON, można rozpakować DataTable do listy, która może być następnie serializowana.

Następująca funkcja zamienia dowolny DataTable na łańcuch JSON (bez uprzedniej wiedzy o nazwach pól lub typach danych):

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);
}
 23
Author: Karl Wenzel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 20:48:38

Możesz użyć JSON.NET biblioteka: http://json.codeplex.com / do serializacji / deserializacji danych.

string json = JsonConvert.SerializeObject(table);

Który serializuje się do czegoś takiego:

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

Jeśli chcesz serializować więcej informacji o DataTable np. schemat kolumny, klucz główny, nazwa tabeli, możesz użyć niestandardowego konwertera, który napisałem: https://github.com/chris-herring/DataTableConverter . Użyj go tak:

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

Który serializuje się do czegoś takiego:

{
    "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"]
}
 14
Author: Chris Herring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 02:39:19

Dzięki Ariel. Twoja odpowiedź była bardzo pomocna. Oto wersja, która opiera się na twojej odpowiedzi.

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();
}
 7
Author: Dan Randolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-23 02:36:31

Dziękuję Karl Wenzel. Miałem problem, w którym mogłem odbierać tylko tabelę danych ze starego serwisu internetowego asmx. Teraz napisałem stronę, która może parsować te dane i zwracać je w 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);
}
 3
Author: Gil Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-11 12:54:42

Alternatywny sposób bez użycia serializera javascript:

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
Author: Durai Amuthan.H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-11 13:47:00

Używam 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()
);
 2
Author: Roman Martynenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-23 09:30:46