Чтение из CSV и преобразование объекта в JSON

Я читаю строки из файла CSV и загружаю список объектов. Мне нужно преобразовать каждый объект в JSON, но все, что я пробовал до сих пор, например JsonConvert.SerializeObject, не сработает.

Строка выглядит точно так же, как показано ниже (скопировано из CSV):

{ email = [email protected], name = Premium Dois CEDRO, ip = 0.0.0.1,
action = login, timeStamp = 2019-06-12 13:30:11Z }

Когда я читаю и загружаю, объект выглядит так:

"{ email = [email protected], name = Premium Dois CEDRO, ip = 0.0.0.1,
action = login, timeStamp = 11/06/2019 17:44:03 }"

Когда он загружается в список, запятые помещаются в объекты, а вокруг каждого объекта заключаются двойные кавычки. Наконец, когда я использую SerializeObject, он возвращает это:

"[\"{ email = [email protected], name = Premium Dois CEDRO, ip =
0.0.0.1, action = login, timeStamp = 2019-06-12 13:30:11Z }\"

Вывод, который мне нужен, это Json, подобный этому:

{
  "email": "[email protected]",
  "name": "Premium Dois CEDRO",
  "ip": "0.0.0.1",
  "action": "login",
  "timeStamp": "2019-06-11T18:50:02.0091122Z"
}

Код для чтения из файла и списка загрузки:

using (var reader = new StreamReader($"{filePath}CONTINGENCY AUDIT LOG.csv"))
                {
                List<object> contingencyList = new List<object>();

                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    contingencyList.Add(line);
                }
                string jsonList = JsonConvert.SerializeObject(contingencyList);
                    reader.Close();
                return contingencyList;
                }

Код для перебора списка:

foreach (object item in contingencyList)
            { Console.WriteLine(item);
                }

Вам нужно разобрать CSV в класс, а затем сериализовать его как json. Струны — это просто струны.

Neil 12.06.2019 15:49

Этот ввод уже json. Не нужно когда-либо рассматривать его как csv.

Joel Coehoorn 12.06.2019 15:53

Ваш пример не похож на типичное содержимое файла CSV.

André Sanson 12.06.2019 15:55

@Neil Я не уверен, что смогу использовать класс, потому что файл CSV будет заполнен множеством разных полей. Я использую CSV для сбора ряда данных, которые позже будут отправлены в MongoDB.

Pablo Sylar 12.06.2019 15:56

Конечно, можешь, Пабло. Должна быть какая-то схема для JSON. Вы просто вставляете JSON в VS, затем выбираете «Вставить как классы» в меню редактирования, и у вас будут классы, соответствующие схеме.

Neil 12.06.2019 15:58

@PabloSylar Вы можете изменить формат файла? Потому что, как упоминали другие люди, образец, который вы показали, не имеет формата csv.

Nico Schreiner 12.06.2019 16:07

@Nico Schreiner Я сохраняю объекты в CSV. Я не могу назвать столбцы после каждого ключа, потому что будет диапазон разных данных, поэтому каждая строка является объектом.

Pablo Sylar 12.06.2019 17:07

@Neil Но, как я уже сказал, у меня будет много разных полей для каждого файла Json. Как я объяснил ниже, теперь я признаю, что нужен другой подход, поэтому мне придется начать использовать файлы .json вместо CSV. В любом случае, спасибо.

Pablo Sylar 12.06.2019 17:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
445
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Даже если исходный формат не похож на файл .csv, шаги, которые необходимо выполнить для реализации такого рода задач, следующие:

  1. Чтение CSV-файла построчно
  2. Разберите каждую строку и заполните свойства класса, представляющего объект. Вы можете передать конструктору класса строку (строку .csv, которую вы только что прочитали) и проанализировать ее здесь, заполнив все свойства.
public class MyClass
{
    public string Email { get; set; }
    public string Name {get; set; }
    // ... and so on with other properties

    public MyClass(string csvLine)
    {
        // Here parse the line and fill the properties
    }
}
  1. Переопределите функцию ToString() в этом классе и выполните здесь сериализацию JSON (используя, например, функцию System.Web.Script.Serialization.JavaScriptSerializer().Serialize(string):
public class MyClass
{      
    // ...

    public override string ToString()
    {
        return new JavaScriptSerializer().Serialize(this);
    }
}

Ваш код будет примерно таким:

while (!reader.EndOfStream)
{
    var line = reader.ReadLine();
    MyClass mc = new MyClass(line);
    string jsonString = mc.ToString();
}
Ответ принят как подходящий

Если возможно, получите правильный формат CSV-файла, удалив описания столбцов, такие как email =, и обязательно установите правильный разделитель столбцов, например ;. В итоге ваш файл должен выглядеть так:

[email protected];ExampleName;127.0.0.1;login;2019-06-12 13:30:11Z
[email protected];ExampleName2;0.0.0.1;logout;2019-06-12 13:30:11Z

Затем определите новый класс:

public class CSVEntry
{
    public string Email { get; set }
    public string Name { get; set; }
    public IPAddress IPAddress { get; set; }
    public string Action { get; set; } 
    public DateTime Timestamp { get; set; }       

    public CSVEntry(string email, string name, IPAddress ip, string action, DateTime timestamp)
    {
        Email = email;
        Name = name;
        IPAddress = ip;
        Action = action;
        Timestamp = timestamp;
    }

    public static CSVEntry Parse(string csvLine)
    {
        string[] args = csvLine.Split(';');

        if (args.Length >= 5)
        {
            string email = args[0];
            string name = args[1];
            IPAddress ip = IPAddress.Parse(args[2]);
            string action = args[3];
            DateTime timestamp = DateTime.Parse(args[4]);

            return new CSVEntry(email, name, ip, action, timestamp);
        }

        return null;
    }
}

Если вы не можете изменить формат, вам нужно проанализировать строку csv, используя другой метод, например regex.

Затем просмотрите CSV-файл построчно, создайте объект с помощью CSVEntry.Parse(line); и добавьте его в List<CSVEntry>, например:

var list = new List<CSVEntry>();

while (!reader.EndOfStream)
{
    string line = reader.ReadLine();
    list.Add(CSVEntry.Parse(line));
}

Затем вы можете сериализовать его, используя JsonConvert.SerializeObject(list);

Это сработало бы, если бы в моем файле был только один тип данных, из которых я мог бы создать класс. Я приму это как ответ для будущих ссылок, но после стольких раз по этому вопросу я решил начать создавать и использовать файлы .json. В любом случае, большое спасибо.

Pablo Sylar 12.06.2019 17:13

Другие вопросы по теме