0

I want to generate json from datatable, and I've tried this

public static JsonResult ConvertFromDataTable(DataTable dataTable)
    {
        var result = new List<dynamic>();
        foreach (DataRow row in dataTable.Rows)
        {
            dynamic dyn = new ExpandoObject();
            foreach (DataColumn column in dataTable.Columns)
            {
                var dic = (IDictionary<string, object>)dyn;
                dic[column.ColumnName] = row[column];
            }
            result.Add(dyn);
        }

        string _json = JsonConvert.SerializeObject(result);

        var resultJSON = new JsonResult
        {
            Data = JsonConvert.DeserializeObject(_json),
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };

        return resultJSON;
    }

but the result always have "ContentEncoding", "ContentType" on my json,

{
"ContentEncoding": null,
"ContentType": null,
"Data": [
    {
        "Name": "Steve",
        "Age": "30",
        "Photo": "steve.png",
        "Gender": "Male"
    },
    {
        "Name": "Sarah",
        "Age": "19",
        "Photo": "sarah.png",
        "Gender": "Female"
    }
],
"JsonRequestBehavior": 0,
"MaxJsonLength": null,
"RecursionLimit": null
}

I just need "Data" on my json, its possible to remove that?

Noob
  • 55
  • 8

2 Answers2

0

This is only an example on how you could do it.

I would prefer this way because:

  1. When your return strongly-typed data your controller is more readable. It is clear for your (and your teammates) - what data will be returned from this controller.

  2. I would recommend avoiding dynamic type usage everywhere where it is possible. You could read more about it there When should one use dynamic keyword in c# 4.0?

Code:

public class Person
{
    public string Name { get; set; }
    public string Age { get; set; }
    public string Photo { get; set; }
    public string Gender { get; set; }
}

public static List<Person> ConvertFromDataTable(DataTable dataTable)
{
    var result = new List<Person>();

    foreach (DataRow row in dataTable.Rows)
    {
        var person = new Person();

        foreach (DataColumn column in dataTable.Columns)
        {
            switch (column.ColumnName)
            {
                case "Name":
                    person.Name = row[column].ToString();break;

                case "Age":
                    person.Age = row[column].ToString(); break;

                case "Photo":
                    person.Name = row[column].ToString(); break;

                case "Gender":
                    person.Name = row[column].ToString(); break;
            }
        }

        result.Add(person);
    }

    return result;
}

//your api method there
public List<Person> GetPersons()
{
    DataTable dt = new DataTable();
    //here you populate your DataTable
    return ConvertFromDataTable(dt);
}

Also, you could make some generic extension to convert your DataTable to typed objects , you could see an example there : How to Convert DataTable to Generic List in C#

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Roman Kalinchuk
  • 718
  • 3
  • 14
-1

You can easily convert it using Newtonsoft JSON library

    DataTable table = new DataTable();
    DataColumn idColumn = new DataColumn("id", typeof(int));
    idColumn.AutoIncrement = true;

    DataColumn itemColumn = new DataColumn("item");
    table.Columns.Add(idColumn);
    table.Columns.Add(itemColumn);


    for (int i = 0; i < 2; i++)
    {
        DataRow newRow = table.NewRow();
        newRow["item"] = "item " + i;
        table.Rows.Add(newRow);
    }

    //produces formatted string, to avoid it omit the parameter from the method call
    string json = JsonConvert.SerializeObject(table, Formatting.Indented);
    

Output

[
  {
    "id": 0,
    "item": "item 0"
  },
  {
    "id": 1,
    "item": "item 1"
  }
]

Please refer the fiddle here

Reference https://www.newtonsoft.com/json/help/html/SerializeDataSet.htm

Amal Dev
  • 1,938
  • 1
  • 14
  • 26
  • the output is string right? I've tried your method but the result like this: "[\r\n {\r\n \"Name\": \"Steve\",\r\n \"Age\": \"30\",\r\n \"Photo\": \"steve.png\",\r\n \"Gender\": \"Male\" },\r\n {\r\n \"Name\": \"Sarah\",\r\n \"Age\": \"19\",\r\n \"Photo\": \"sarah.png\",\r\n \"Gender\": \"Female\" }\r\n]" – Noob Jun 22 '20 at 06:40
  • You can turn off the indentation property to avoid the newline and carriage return. Refer the updated fiddle here https://dotnetfiddle.net/PSg5oW – Amal Dev Jun 22 '20 at 07:10