将JSON数据转换为dataTable

我试图将嵌套的Json数组字符串转换为dataTable。 我的代码工作正常,创建精细的数据表。 但现在客户需求发生变化,我正在努力寻找出路以获得以下结构。

要求是每当Json Value是一个数组时,数据应该作为单独的行。

任何帮助真的很感激!!

示例JSON结构:

{“A”:“A0”,“B”:{“B2”:“B2-Val”,“B3”:[{“B30”:“B30 – Val1”,“B31”:“B31 – Val1”} ]},“C”:[“C0”,“C1”]}

当前DataTable输出结构:

在此处输入图像描述

必需的DataTable结构:

在此处输入图像描述

原始C#代码:

public DataTable JsonStringToDataTable(string jsonString) { LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Enters", LogLevel.Debug); DataTable dt = new DataTable(); List lstColumnName = new List(); List lstRowData = new List(); try { lstColumnName = ConvertJsonToList(jsonString, false); foreach (string AddColumnName in lstColumnName) { DataColumnCollection columns = dt.Columns; string colName = AddColumnName.ToLower(); if (!columns.Contains(colName)) { dt.Columns.Add(colName); } } lstRowData = ConvertJsonToList(jsonString, true); DataRow nr = dt.NewRow(); for (int i = 0; i < lstRowData.Count; i++) { try { string RowColumns = lstColumnName[i]; string RowDataString = lstRowData[i]; nr[RowColumns] = RowDataString; } catch (Exception ex) { //continue; throw ex; } } dt.Rows.Add(nr); } catch (Exception ex) { LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Error while creating datatable from JSON string :: " + ex.Message, LogLevel.Debug); throw ex; } finally { LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Exits", LogLevel.Debug); } return dt; } public static List ConvertJsonToList(string jsonString, bool isValue) { LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Enters", LogLevel.Debug); DataTable dt = new DataTable(); var jObj = JObject.Parse(jsonString); List lstData = new List(); try { if (isValue) { lstData = AddJsonObjects(jObj, "JSON", lstData, true, false); } else { lstData = AddJsonObjects(jObj, "JSON", lstData, false, false); } } catch (Exception ex) { LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Error :: " + ex.Message, LogLevel.Debug); throw ex; } finally { LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Exits", LogLevel.Debug); } return lstData; } public static List AddJsonObjects(JObject jObj, string name, List ColumnsName, bool isValue, bool isArrayObject) { foreach (var property in jObj.Properties()) { string strName = name + "." + property.Name; if (isArrayObject && !isValue) { ColumnsName = AddTokenValues(property.Value, strName, ColumnsName, isValue, true); } else { ColumnsName = AddTokenValues(property.Value, property.Name, ColumnsName, isValue, false); } } return ColumnsName; } public static List AddTokenValues(JToken token, string name, List ColumnsName, bool isValue, bool isArrayObject) { if (token is JValue) { if (isValue) { string value = string.Empty; if (token.Type != JTokenType.Null) { value = ((JValue)token).Value.ToString(); } ColumnsName.Add(value); } else { ColumnsName.Add(name); } } else if (token is JArray) { ColumnsName = AddArrayValues((JArray)token, name, ColumnsName, isValue); } else if (token is JObject) { ColumnsName = AddJsonObjects((JObject)token, name, ColumnsName, isValue, true); } return ColumnsName; } public static List AddArrayValues(JArray array, string name, List dataList, bool isValue) { for (var i = 0; i < array.Count; i++) { dataList = AddTokenValues(array[i], string.Format("[{0}]", name + "[" + i.ToString() + "]"), dataList, isValue, true); } return dataList; } 

你去了 – 它不漂亮,需要进一步测试和清理(例如对类中的单独关注并摆脱那些全局变量!)但它会为你提供你所追求的东西。 将下面的代码粘贴到新的控制台应用程序中(粘贴Program.cs的内容)并添加System.Web.Extensions作为参考。

祝好运!

 using System; using System.Collections.Generic; using System.Data; using System.Web.Script.Serialization; namespace ConsoleApplication1 { class Program { private static DataTable dt; private static Dictionary columnRowManager; static void Main(string[] args) { //var json = "[{'firstName':'John', 'lastName':'Doe'},{'firstName':'Anna', 'lastName':'Smith'},{'firstName':'Peter','lastName': 'Jones'} ]"; //var json = "{ 'glossary': { 'title': 'example glossary','GlossDiv': { 'title': 'S','GlossList': { 'GlossEntry': { 'ID': 'SGML','SortAs': 'SGML','GlossTerm': 'Standard Generalized Markup Language','Acronym': 'SGML','Abbrev': 'ISO 8879:1986','GlossDef': { 'para': 'A meta-markup language, used to create markup languages such as DocBook.','GlossSeeAlso': ['GML', 'XML'] },'GlossSee': 'markup' } } } } }"; var json = "{ 'A': 'A0' , 'B' : { 'B2' : 'B2 - Val', 'B3' : [{'B30' : 'B30 - Val1' ,'B31' : 'B31 - Val1'}]}, 'C': ['C0', 'C1']}"; var jss = new JavaScriptSerializer(); dt = new DataTable(); columnRowManager = new Dictionary(); try { // Deal with an object root var dict = jss.Deserialize>(json); GetColumnsAndRowsFromJsonDictionary(dict); } catch (InvalidOperationException ioX) { // Deal with an Array Root var dictionaries = jss.Deserialize[]>(json); foreach (var dict in dictionaries) { GetColumnsAndRowsFromJsonDictionary(dict); } } DumpTableToConsole(); } private static void DumpTableToConsole() { WriteColumnsToConsole(); WriteRowsToConsole(); Console.ReadKey(); } private static void WriteRowsToConsole() { // Write out the Rows foreach (DataRow row in dt.Rows) { foreach (DataColumn col in dt.Columns) { Console.Write(row[col.ColumnName].ToString().PadRight(12) + ","); } Console.WriteLine(); } } private static void WriteColumnsToConsole() { foreach (DataColumn col in dt.Columns) { Console.Write(col.ColumnName.PadRight(12) + ","); } Console.WriteLine(); Console.WriteLine("-------------------------------------------------------------------------------"); } private static void AddDataToTable(string column, string cellValue) { AddColumnIfNew(column); int targetRowPosition = DetermineTargetRow(column); AddRowIfRequired(targetRowPosition); dt.Rows[targetRowPosition - 1][column] = cellValue; } private static void AddRowIfRequired(int targetRowPosition) { if (dt.Rows.Count < targetRowPosition) { dt.Rows.Add(); } } private static int DetermineTargetRow(string column) { int targetRowPosition; columnRowManager.TryGetValue(column, out targetRowPosition); targetRowPosition++; columnRowManager[column] = targetRowPosition; return targetRowPosition; } private static void AddColumnIfNew(string column) { if (!dt.Columns.Contains(column)) { dt.Columns.Add(new DataColumn(column, typeof(String))); columnRowManager.Add(column, 0); } } private static void GetColumnsAndRowsFromJsonDictionary(Dictionary dictionary) { // Catch the curse of recursion - null is your friend (enemy!) if (dictionary == null) return; foreach (var kvp in dictionary) { if (kvp.Value.GetType() == typeof(Dictionary)) { // Process an embedded dictionary (hierarchy) var subDictionary = kvp.Value as Dictionary; GetColumnsAndRowsFromJsonDictionary(subDictionary); } else if (kvp.Value.GetType() == typeof(System.Collections.ArrayList)) { ProcessArrayList(kvp); } else if (kvp.Value.GetType() == typeof(String)) { AddDataToTable(kvp.Key, kvp.Value.ToString()); } else { throw new NotSupportedException(string.Format("Err2: Type '{0}' not supported", kvp.Value.GetType().ToString())); } } } private static void ProcessArrayList(KeyValuePair kvp) { // Process each independant item in the array list foreach (var arrItem in kvp.Value as System.Collections.ArrayList) { if (arrItem.GetType() == typeof(String)) { AddDataToTable(kvp.Key, arrItem.ToString()); } else if (arrItem.GetType() == typeof(Dictionary)) { var subArrDictionary = arrItem as Dictionary; GetColumnsAndRowsFromJsonDictionary(subArrDictionary); } else { throw new NotSupportedException(string.Format("Err1: Type '{0}' not supported", arrItem.GetType().ToString())); } } } } }