Вложенные JSON данные в таблицу данных динамически C# - PullRequest
0 голосов
/ 09 июля 2020
{
    "STATUS": "OK",
    "projects": [
        {
            "startDate": "",
            "last-changed-on": "2019-01-03T11:46:14Z",
            "logo": "",
            "created-on": "2018-12-12T10:04:47Z",
            "privacyEnabled": false,
            "status": "active",
            "boardData": {},
            "replyByEmailEnabled": true,
            "harvest-timers-enabled": false,
            "description": "",
            "category": {
                "color": "",
                "id": "",
                "name": ""
            },
            "id": "322852",
            "overview-start-page": "default",
            "start-page": "projectoverview",
            "integrations": {
                "xero": {
                    "basecurrency": "",
                    "countrycode": "",
                    "enabled": false,
                    "connected": "NO",
                    "organisation": ""
                },
                "sharepoint": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                },
                "microsoftConnectors": {
                    "enabled": false
                },
                "onedrivebusiness": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                }
            },
            "defaults": {
                "privacy": ""
            },
            "notifyeveryone": false,
            "filesAutoNewVersion": false,
            "defaultPrivacy": "open",
            "tasks-start-page": "default",
            "starred": false,
            "announcementHTML": "",
            "isProjectAdmin": true,
            "name": "Project 2",
            "company": {
                "is-owner": "1",
                "id": "78494",
                "name": "MCG Company"
            },
            "endDate": "",
            "announcement": "",
            "show-announcement": false,
            "subStatus": "current",
            "tags": []
        },
        {
            "startDate": "",
            "last-changed-on": "2018-12-11T17:52:57Z",
            "logo": "",
            "created-on": "2018-11-26T11:11:00Z",
            "privacyEnabled": false,
            "status": "active",
            "boardData": {},
            "replyByEmailEnabled": true,
            "harvest-timers-enabled": false,
            "description": "",
            "category": {
                "color": "",
                "id": "",
                "name": ""
            },
            "id": "321041",
            "overview-start-page": "default",
            "portfolioBoards": [
                {
                    "card": {
                        "id": "4771"
                    },
                    "board": {
                        "id": "544",
                        "name": "Project Implementations",
                        "color": "#F39C12"
                    },
                    "column": {
                        "id": "1573",
                        "name": "Go Live",
                        "color": "#F1C40F"
                    }
                }
            ],
            "start-page": "projectoverview",
            "integrations": {
                "xero": {
                    "basecurrency": "",
                    "countrycode": "",
                    "enabled": false,
                    "connected": "NO",
                    "organisation": ""
                },
                "sharepoint": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                },
                "microsoftConnectors": {
                    "enabled": false
                },
                "onedrivebusiness": {
                    "account": "",
                    "foldername": "root",
                    "enabled": false,
                    "folder": "root"
                }
            },
            "defaults": {
                "privacy": ""
            },
            "notifyeveryone": false,
            "filesAutoNewVersion": false,
            "defaultPrivacy": "open",
            "tasks-start-page": "default",
            "starred": false,
            "announcementHTML": "",
            "isProjectAdmin": true,
            "name": "Project One",
            "company": {
                "is-owner": "1",
                "id": "78494",
                "name": "MCG Company"
            },
            "endDate": "",
            "announcement": "",
            "show-announcement": false,
            "subStatus": "current",
            "tags": []
        }
    ]
}

Это JSON ответ, который я получаю от приложения, и есть много других получаемых API, которые возвращают тот же тип ответа (вложенный), поэтому это нужно делать динамически. поскольку пользователь добавляет вызовы API из файла конфигурации, я не могу создавать готовые классы с помощью get и sets. Моя цель - преобразовать эти данные в таблицу данных для вставки в базу данных. Когда я вижу вложенный столбец, моя цель - прикрепить к нему имя родительского столбца с помощью символа «_» ex: category_id = "" или integration_xero_basecurrency = " ", et c ..

Это код, который я использовал для табулирования данных, но в коде он принимает только столбец, если это JValue (ключ и значение), а я не в состоянии, хоть убей, создать правильный l oop, который добьется цели.

    public DataTable Tabulate(string jsonContent)
    {
        var jsonLinq = JObject.Parse(jsonContent);

        // Find the first array using Linq
        var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
        //Console.WriteLine("extarcted data:" + srcArray);
        var trgArray = new JArray();
        foreach (JObject row in srcArray.Children<JObject>())
        {
            var cleanRow = new JObject();
            foreach (JProperty column in row.Properties())
            {
                // Only include JValue types
                if (column.Value is JValue)
                {
                    cleanRow.Add(column.Name, column.Value);
                }
            }

            trgArray.Add(cleanRow);
        }

        DataTable dt = JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());            

        return dt;
    }

1 Ответ

1 голос
/ 09 июля 2020

Как насчет примерно этого:

public DataTable Tabulate(string jsonContent)
{
    var jsonLinq = JObject.Parse(jsonContent);

    // Find the first array using Linq
    var arrayProp = jsonLinq.Properties().First(p => p.Value is JArray);
    var srcArray = (JArray)arrayProp.Value;

    // Set up a regex consisting of the array property name and subscript 
    // (e.g. "projects[0]."), which we will strip off
    var regex = new Regex($@"^{arrayProp.Name}\[\d+\]\.");

    // Flatten each object of the original array 
    // into new objects and put them in a new array 
    var trgArray = new JArray(
        srcArray.Children<JObject>()
                .Select(row => new JObject(
                     row.Descendants()
                        .OfType<JProperty>()
                        .Where(p => p.Value is JValue)
                        .Select(p => new JProperty(
                            regex.Replace(p.Value.Path, "").Replace(".", "_"), 
                            p.Value
                        ))
                ))
        );

    // Convert the new array to a DataTable
    DataTable dt = trgArray.ToObject<DataTable>();

    return dt;
}

Рабочая демонстрация: https://dotnetfiddle.net/yrmcSQ

...