- Eu quero obter os registros do banco de dados em um
DataTable
. - Em seguida, converta o
DataTable
em um objeto JSON. - Retorne o objeto JSON para minha função JavaScript.
Eu uso este código ligando para:
string result = JsonConvert.SerializeObject(DatatableToDictionary(queryResult, "Title"), Newtonsoft.Json.Formatting.Indented);
Para converter um DataTable em JSON, ele funciona corretamente e retorna o seguinte:
{
"1": {
"viewCount": 703,
"clickCount": 98
},
"2": {
"viewCount": 509,
"clickCount": 85
},
"3": {
"viewCount": 578,
"clickCount": 86
},
"4": {
"viewCount": 737,
"clickCount": 108
},
"5": {
"viewCount": 769,
"clickCount": 130
}
}
Mas eu gostaria que ele retornasse o seguinte:
{"records":[
{
"Title": 1,
"viewCount": 703,
"clickCount": 98
},
{
"Title": 2,
"viewCount": 509,
"clickCount": 85
},
{
"Title": 3,
"viewCount": 578,
"clickCount": 86
},
{
"Title": 4,
"viewCount": 737,
"clickCount": 108
},
{
"Title": 5,
"viewCount": 769,
"clickCount": 130
}
]}
Como posso fazer isso?
Respostas:
Este trecho de código de Convert Datatable to JSON String em C #, VB.NET pode ajudá-lo. Ele usa System.Web.Script.Serialization.JavaScriptSerializer para serializar o conteúdo no formato JSON:
public string ConvertDataTabletoString() { DataTable dt = new DataTable(); using (SqlConnection con = new SqlConnection("Data Source=SureshDasari;Initial Catalog=master;Integrated Security=true")) { using (SqlCommand cmd = new SqlCommand("select title=City,lat=latitude,lng=longitude,description from LocationDetails", con)) { con.Open(); SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(dt); System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); Dictionary<string, object> row; foreach (DataRow dr in dt.Rows) { row = new Dictionary<string, object>(); foreach (DataColumn col in dt.Columns) { row.Add(col.ColumnName, dr[col]); } rows.Add(row); } return serializer.Serialize(rows); } } }
fonte
Podemos realizar a tarefa de duas maneiras simples, uma usando Json.NET dll e a outra usando a classe StringBuilder.
Usando Newtonsoft Json.NET
string JSONresult; JSONresult = JsonConvert.SerializeObject(dt); Response.Write(JSONresult);
Link de referência: Newtonsoft: Converter DataTable em objeto JSON em ASP.Net C #
Usando StringBuilder
public string DataTableToJsonObj(DataTable dt) { DataSet ds = new DataSet(); ds.Merge(dt); StringBuilder JsonString = new StringBuilder(); if (ds != null && ds.Tables[0].Rows.Count > 0) { JsonString.Append("["); for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { JsonString.Append("{"); for (int j = 0; j < ds.Tables[0].Columns.Count; j++) { if (j < ds.Tables[0].Columns.Count - 1) { JsonString.Append("\"" + ds.Tables[0].Columns[j].ColumnName.ToString() + "\":" + "\"" + ds.Tables[0].Rows[i][j].ToString() + "\","); } else if (j == ds.Tables[0].Columns.Count - 1) { JsonString.Append("\"" + ds.Tables[0].Columns[j].ColumnName.ToString() + "\":" + "\"" + ds.Tables[0].Rows[i][j].ToString() + "\""); } } if (i == ds.Tables[0].Rows.Count - 1) { JsonString.Append("}"); } else { JsonString.Append("},"); } } JsonString.Append("]"); return JsonString.ToString(); } else { return null; } }
fonte
Isso tem uma abordagem semelhante à resposta aceita, mas usa LINQ para converter a tabela de dados para listar em uma única linha de código.
//convert datatable to list using LINQ. Input datatable is "dt", returning list of "name:value" tuples var lst = dt.AsEnumerable() .Select(r => r.Table.Columns.Cast<DataColumn>() .Select(c => new KeyValuePair<string, object>(c.ColumnName, r[c.Ordinal]) ).ToDictionary(z=>z.Key,z=>z.Value) ).ToList(); //now serialize it var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); return serializer.Serialize(lst);
Esta é uma maneira incrivelmente útil de enumerar uma tabela de dados, o que normalmente exigiria uma tonelada de codificação! Aqui estão algumas variações:
//convert to list with array of values for each row var list1 = dt.AsEnumerable().Select(r => r.ItemArray.ToList()).ToList(); //convert to list of first column values only var list2 = dt.AsEnumerable().Select(r => r.ItemArray[0]).ToList(); // parse a datatable with conditions and get CSV string string MalesOver21 = string.Join(",", dt.AsEnumerable() .Where(r => r["GENDER"].ToString()=="M" && r.Field<int>("AGE")>21) .Select(r => r.Field<string>("FULLNAME")) );
Isso está fora do tópico da pergunta original, mas para fins de completude, eu mencionaria que se você quiser apenas filtrar as linhas de uma tabela de dados existente, veja esta resposta
fonte
Uma maneira alternativa sem usar o serializador 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()); } //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]", ""); }
fonte
Você pode usar a mesma forma especificada por Alireza Maddah e se quiser usar duas tabelas de dados em uma matriz json a seguir é a maneira:
public string ConvertDataTabletoString() { DataTable dt = new DataTable(); DataTable dt1 = new DataTable(); using (SqlConnection con = new SqlConnection("Data Source=SureshDasari;Initial Catalog=master;Integrated Security=true")) { using (SqlCommand cmd = new SqlCommand("select title=City,lat=latitude,lng=longitude,description from LocationDetails", con)) { con.Open(); SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(dt); System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); Dictionary<string, object> row; foreach (DataRow dr in dt.Rows) { row = new Dictionary<string, object>(); foreach (DataColumn col in dt.Columns) { row.Add(col.ColumnName, dr[col]); } rows.Add(row); } SqlCommand cmd1 = new SqlCommand("_another_query_", con); SqlDataAdapter da1 = new SqlDataAdapter(cmd1); da1.Fill(dt1); System.Web.Script.Serialization.JavaScriptSerializer serializer1 = new System.Web.Script.Serialization.JavaScriptSerializer(); Dictionary<string, object> row1; foreach (DataRow dr in dt1.Rows) //use the old variable rows only { row1 = new Dictionary<string, object>(); foreach (DataColumn col in dt1.Columns) { row1.Add(col.ColumnName, dr[col]); } rows.Add(row1); // Finally You can add into old json array in this way } return serializer.Serialize(rows); } } }
Da mesma forma, pode ser usado para quantas tabelas de dados você desejar.
fonte
Converter tabela de dados para JSON usando C # .net
public static object 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] = (Convert.ToString(row[col])); } list.Add(dict); } JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(list); }
fonte
Experimente esta função personalizada.
public static string DataTableToJsonObj(DataTable dt) { DataSet ds = new DataSet(); ds.Merge(dt); StringBuilder jsonString = new StringBuilder(); if (ds.Tables[0].Rows.Count > 0) { jsonString.Append("["); for (int rows = 0; rows < ds.Tables[0].Rows.Count; rows++) { jsonString.Append("{"); for (int cols = 0; cols < ds.Tables[0].Columns.Count; cols++) { jsonString.Append(@"""" + ds.Tables[0].Columns[cols].ColumnName + @""":"); /* //IF NOT LAST PROPERTY if (cols < ds.Tables[0].Columns.Count - 1) { GenerateJsonProperty(ds, rows, cols, jsonString); } //IF LAST PROPERTY else if (cols == ds.Tables[0].Columns.Count - 1) { GenerateJsonProperty(ds, rows, cols, jsonString, true); } */ var b = (cols < ds.Tables[0].Columns.Count - 1) ? GenerateJsonProperty(ds, rows, cols, jsonString) : (cols != ds.Tables[0].Columns.Count - 1) || GenerateJsonProperty(ds, rows, cols, jsonString, true); } jsonString.Append(rows == ds.Tables[0].Rows.Count - 1 ? "}" : "},"); } jsonString.Append("]"); return jsonString.ToString(); } return null; } private static bool GenerateJsonProperty(DataSet ds, int rows, int cols, StringBuilder jsonString, bool isLast = false) { // IF LAST PROPERTY THEN REMOVE 'COMMA' IF NOT LAST PROPERTY THEN ADD 'COMMA' string addComma = isLast ? "" : ","; if (ds.Tables[0].Rows[rows][cols] == DBNull.Value) { jsonString.Append(" null " + addComma); } else if (ds.Tables[0].Columns[cols].DataType == typeof(DateTime)) { jsonString.Append(@"""" + (((DateTime)ds.Tables[0].Rows[rows][cols]).ToString("yyyy-MM-dd HH':'mm':'ss")) + @"""" + addComma); } else if (ds.Tables[0].Columns[cols].DataType == typeof(string)) { jsonString.Append(@"""" + (ds.Tables[0].Rows[rows][cols]) + @"""" + addComma); } else if (ds.Tables[0].Columns[cols].DataType == typeof(bool)) { jsonString.Append(Convert.ToBoolean(ds.Tables[0].Rows[rows][cols]) ? "true" : "fasle"); } else { jsonString.Append(ds.Tables[0].Rows[rows][cols] + addComma); } return true; }
fonte
Para acessar o valor da tabela de dados convertido no método Json, siga as etapas abaixo:
$.ajax({ type: "POST", url: "/Services.asmx/YourMethodName", data: "{}", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { var parsed = $.parseJSON(data.d); $.each(parsed, function (i, jsondata) { $("#dividtodisplay").append("Title: " + jsondata.title + "<br/>" + "Latitude: " + jsondata.lat); }); }, error: function (XHR, errStatus, errorThrown) { var err = JSON.parse(XHR.responseText); errorMessage = err.Message; alert(errorMessage); } });
fonte
Muito simples nos dias de hoje ..
string json = JsonConvert.SerializeObject(YourDataTable, Formatting.Indented);
Agora converta seu Json em um DataTable:
YourDataTable = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
Funciona para DataSets também.
fonte
Eu tenho uma função simples para converter tabela de dados em string json.
Usei o Newtonsoft para gerar string. Eu não uso o Newtonsoft para serializar totalmente Datatable. Tenha cuidado com isso.
Talvez isso possa ser útil.
private string DataTableToJson(DataTable dt) { if (dt == null) { return "[]"; }; if (dt.Rows.Count < 1) { return "[]"; }; JArray array = new JArray(); foreach(DataRow dr in dt.Rows) { JObject item = new JObject(); foreach(DataColumn col in dt.Columns) { item.Add(col.ColumnName, dr[col.ColumnName]?.ToString()); } array.Add(item); } return array.ToString(Newtonsoft.Json.Formatting.Indented); }
fonte
tente isto (ExtensionMethods):
public static string ToJson(this DataTable dt) { List<Dictionary<string, object>> lst = new List<Dictionary<string, object>>(); Dictionary<string, object> item; foreach (DataRow row in dt.Rows) { item = new Dictionary<string, object>(); foreach (DataColumn col in dt.Columns) { item.Add(col.ColumnName, (Convert.IsDBNull(row[col]) ? null : row[col])); } lst.Add(item); } return Newtonsoft.Json.JsonConvert.SerializeObject(lst); }
E use:
DataTable dt = new DataTable(); . . . var json = dt.ToJson();
fonte
Com Cinchoo ETL - uma biblioteca de código aberto, você pode exportar DataTable para JSON facilmente com poucas linhas de código
StringBuilder sb = new StringBuilder(); string connectionstring = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True"; using (var conn = new SqlConnection(connectionstring)) { conn.Open(); var comm = new SqlCommand("SELECT * FROM Customers", conn); SqlDataAdapter adap = new SqlDataAdapter(comm); DataTable dt = new DataTable("Customer"); adap.Fill(dt); using (var parser = new ChoJSONWriter(sb)) parser.Write(dt); } Console.WriteLine(sb.ToString());
Resultado:
{ "Customer": [ { "CustomerID": "ALFKI", "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "ContactTitle": "Sales Representative", "Address": "Obere Str. 57", "City": "Berlin", "Region": null, "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 D.F.", "Region": null, "PostalCode": "05021", "Country": "Mexico", "Phone": "(5) 555-4729", "Fax": "(5) 555-3745" } ] }
fonte
public static string ConvertIntoJson(DataTable dt) { var jsonString = new StringBuilder(); if (dt.Rows.Count > 0) { jsonString.Append("["); for (int i = 0; i < dt.Rows.Count; i++) { jsonString.Append("{"); for (int j = 0; j < dt.Columns.Count; j++) jsonString.Append("\"" + dt.Columns[j].ColumnName + "\":\"" + dt.Rows[i][j].ToString().Replace('"','\"') + (j < dt.Columns.Count - 1 ? "\"," : "\"")); jsonString.Append(i < dt.Rows.Count - 1 ? "}," : "}"); } return jsonString.Append("]").ToString(); } else { return "[]"; } } public static string ConvertIntoJson(DataSet ds) { var jsonString = new StringBuilder(); jsonString.Append("{"); for (int i = 0; i < ds.Tables.Count; i++) { jsonString.Append("\"" + ds.Tables[i].TableName + "\":"); jsonString.Append(ConvertIntoJson(ds.Tables[i])); if (i < ds.Tables.Count - 1) jsonString.Append(","); } jsonString.Append("}"); return jsonString.ToString(); }
fonte
//Common DLL client, server public class transferDataTable { public class myError { public string Message { get; set; } public int Code { get; set; } } public myError Error { get; set; } public List<string> ColumnNames { get; set; } public List<string> DataTypes { get; set; } public List<Object> Data { get; set; } public int Count { get; set; } } public static class ExtensionMethod { public static transferDataTable LoadData(this transferDataTable transfer, DataTable dt) { if (dt != null) { transfer.DataTypes = new List<string>(); transfer.ColumnNames = new List<string>(); foreach (DataColumn c in dt.Columns) { transfer.ColumnNames.Add(c.ColumnName); transfer.DataTypes.Add(c.DataType.ToString()); } transfer.Data = new List<object>(); foreach (DataRow dr in dt.Rows) { foreach (DataColumn col in dt.Columns) { transfer.Data.Add(dr[col] == DBNull.Value ? null : dr[col]); } } transfer.Count = dt.Rows.Count; } return transfer; } public static DataTable GetDataTable(this transferDataTable transfer, bool ConvertToLocalTime = true) { if (transfer.Error != null || transfer.ColumnNames == null || transfer.DataTypes == null || transfer.Data == null) return null; int columnsCount = transfer.ColumnNames.Count; DataTable dt = new DataTable(); for (int i = 0; i < columnsCount; i++ ) { Type colType = Type.GetType(transfer.DataTypes[i]); dt.Columns.Add(new DataColumn(transfer.ColumnNames[i], colType)); } int index = 0; DataRow row = dt.NewRow(); foreach (object o in transfer.Data) { if (ConvertToLocalTime && o != null && o.GetType() == typeof(DateTime)) { DateTime dat = Convert.ToDateTime(o); row[index] = dat.ToLocalTime(); } else row[index] = o == null ? DBNull.Value : o; index++; if (columnsCount == index) { index = 0; dt.Rows.Add(row); row = dt.NewRow(); } } return dt; } } //Server [OperationContract] [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "json/data")] transferDataTable _Data(); public transferDataTable _Data() { try { using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["myConnString"])) { con.Open(); DataSet ds = new DataSet(); SqlDataAdapter myAdapter = new SqlDataAdapter("SELECT * FROM tbGalleries", con); myAdapter.Fill(ds, "table"); DataTable dt = ds.Tables["table"]; return new transferDataTable().LoadData(dt); } } catch(Exception ex) { return new transferDataTable() { Error = new transferDataTable.myError() { Message = ex.Message, Code = ex.HResult } }; } } //Client Response = Vossa.getAPI(serviceUrl + "json/data"); transferDataTable transfer = new JavaScriptSerializer().Deserialize<transferDataTable>(Response); if (transfer.Error == null) { DataTable dt = transfer.GetDataTable(); dbGrid.ItemsSource = dt.DefaultView; } else MessageBox.Show(transfer.Error.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
fonte
Passe a tabela de dados para este método, ele retornaria String json.
public DataTable GetTable() { string str = "Select * from GL_V"; OracleCommand cmd = new OracleCommand(str, con); cmd.CommandType = CommandType.Text; DataTable Dt = OracleHelper.GetDataSet(con, cmd).Tables[0]; return Dt; } public string DataTableToJSONWithJSONNet(DataTable table) { string JSONString = string.Empty; JSONString = JsonConvert.SerializeObject(table); return JSONString; } public static DataSet GetDataSet(OracleConnection con, OracleCommand cmd) { // create the data set DataSet ds = new DataSet(); try { //checking current connection state is open if (con.State != ConnectionState.Open) con.Open(); // create a data adapter to use with the data set OracleDataAdapter da = new OracleDataAdapter(cmd); // fill the data set da.Fill(ds); } catch (Exception ex) { throw; } return ds; }
fonte
Estou usando esta função para descrever a tabela.
Use-o após preencher a tabela de dados
static public string DataTableToJSON(DataTable dataTable,bool readableformat=true) { string JSONString="["; string JSONRow; string colVal; foreach(DataRow dataRow in dataTable.Rows) { if(JSONString!="[") { JSONString += ","; } JSONRow = ""; if (readableformat) { JSONRow += "\r\n"; } JSONRow += "{"; foreach (DataColumn col in dataTable.Columns) { colVal = dataRow[col].ToString(); colVal = colVal.Replace("\"", "\\\""); colVal = colVal.Replace("'", "\\\'"); if(JSONRow!="{"&&JSONRow!="\r\n{") { JSONRow += ","; } JSONRow += "\"" + col.ColumnName + "\":\"" + colVal + "\""; } JSONRow += "}"; JSONString += JSONRow; } JSONString += "\r\n]"; return JSONString; }
Consulta MySQL: "DESCRIBE TableName;"; DataTableToJSON (dataTable) Exemplo de saída:
[ {"Field":"id","Type":"int(5)","Null":"NO","Key":"PRI","Default":"","Extra":"auto_increment"}, {"Field":"ad","Type":"int(11) unsigned","Null":"NO","Key":"MUL","Default":"","Extra":""}, {"Field":"soyad","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"ulke","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"alan","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"numara","Type":"varchar(20)","Null":"NO","Key":"","Default":"","Extra":""} ]
Testado com PHP:
$X='[ {"Field":"id","Type":"int(5)","Null":"NO","Key":"PRI","Default":"","Extra":"auto_increment"}, {"Field":"ad","Type":"int(11) unsigned","Null":"NO","Key":"MUL","Default":"","Extra":""}, {"Field":"soyad","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"ulke","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"alan","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""}, {"Field":"numara","Type":"varchar(20)","Null":"NO","Key":"","Default":"","Extra":""} ]'; $Y=json_decode($X,true); echo $Y[0]["Field"]; var_dump($Y);
fonte
Todas essas respostas são ótimas para mover dados! Onde eles falham é preservar o tipo de coluna dos dados sendo movidos. Isso se torna um problema quando você deseja fazer coisas como mesclar tabelas de dados que parecem iguais.
JsonConvert
examinará a primeira linha de dados para determinar o tipo de dados da coluna, que pode ser adivinhado incorretamente.Para contornar isso;
DataTable
eDataColumn
em objetos de resposta separados.DataColumn
definições na resposta antes de ler na tabela.DataTable
ignorando o esquema definido por Json.Parece muito, mas são apenas três linhas adicionais de código.
// Get our Column definitions and serialize them using an anoymous function. var columns = dt.Columns.Cast<DataColumn>().Select(c => new { DataPropertyName = c.ColumnName, DataPropertyType = c.DataType.ToString()}); resp.ObjSchema = JsonConvert.SerializeObject(columns); resp.Obj = JsonConvert.SerializeObject(dt);
resp.ObjSchema
torna-se;[ { "DataPropertyName": "RowId", "DataPropertyType ": "System.Int32" }, { "DataPropertyName": "ItemName", "DataPropertyType ": "System.String" } ]
Em vez de deixar Json definir as definições de coluna por meio
dt = JsonConvert.DeserializeObject<DataTable>(response)
, podemos usar LINQ em nossoresp.ObjSchema
para defini-las nós mesmos. UsaremosMissingSchemaAction.Ignore
para ignorar o esquema fornecido por Json.// If your environment does not support dynamic you'll need to create a class for with DataPropertyName and DataPropertyType. JsonConvert.DeserializeObject<List<dynamic>>(response.ObjSchema).ForEach(prop => { dt.Columns.Add(new DataColumn() { ColumnName = prop.DataPropertyName, DataType = Type.GetType(prop.DataPropertyType.ToString()) }); }); // Merge the results ignoring the JSON schema. dt.Merge(JsonConvert.DeserializeObject<DataTable>(response.Obj), true, MissingSchemaAction.Ignore);
fonte