0

I have the following models:

public class InputFile
{
    public string Path { get; set; } // absolute path of file

    public string Content { get; set; } // full content of the json file
}

and

public class InputModel
{
    public List<InputFile> Files { get; set; }
}

What I need to do is to read a bunch of JSON files(around 1000) from my hard drive and convert them into the InputModel format. The Path is the absolute path of the file and Content is file content. Note that I am reading only JSON files so the content itself is a JSON file.This is the code:

public void Parse(string collectedInputPath) // Command Line Input
{
    List<string> directories = new List<string>();
    directories.Add(collectedInputPath);
    directories.AddRange(LoadSubDirs(collectedInputPath));
    InputModel input = new InputModel();
    string body = string.Empty;
    foreach(string directory in directories) // Going through all directories
    {                
        foreach (string filePath in Directory.GetFiles(directory)) // Adding every file to the Input Model List
        {
            string content = System.IO.File.ReadAllText(filePath);                    
            string fp = JsonConvert.SerializeObject(filePath);
            string jsonbody = JsonConvert.SerializeObject(content);                    
            body += $"{{\"Path\" : {filePath}, \"Content\": {content}}},";
        }
    }
    body += "]}";
    body = "{\"Files\":[" + body;                
    input = JsonConvert.DeserializeObject<InputModel>(body);
    Solve(input);
}

private List<string> LoadSubDirs(string dir)
{
    string[] subdirectoryEntries = Directory.GetDirectories(dir);
    List<string> subDirectoryList = new List<string>();
    foreach (string subDirectory in subdirectoryEntries)
    {
        subDirectoryList.Add(subDirectory);
        subDirectoryList.AddRange(LoadSubDirs(subDirectory));
    }

    return subDirectoryList;
}

The collectedInputPath is the path of the root directory provided via user input. I have to check inside every directory under the root directory and read every JSON file. I'm getting this error: Error Image

How should I correct this?

Max Play
  • 3,717
  • 1
  • 22
  • 39
  • Print out the JSON string right before you deserialize it to verify that it looks like you expect. – Hans Kilian May 31 '21 at 12:51
  • You need encode content to JSON value. See this : https://stackoverflow.com/questions/1242118/how-to-escape-json-string – vernou May 31 '21 at 12:55
  • @HansKilian I am converting them to my json model. I am generating the path, extracting the content, creating the "body" string in the form of a json string file in accordance with my model and trying to deserialize it. And no all files are not JSON but that should not be the problem. – Akarshan Chatterjee May 31 '21 at 12:56
  • @vernou thanks mate! problem solved! – Akarshan Chatterjee May 31 '21 at 13:09

1 Answers1

0

From your code:

body += $"{{\"Path\" : {filePath}, \"Content\": {content}}},";

filePath and content are strings. So you are missing the quotes " around the property values. And even if you had them, filePath probably contains backslashes \ which must be escaped for JSON. And in the moment, your file content contains a double quote ", your JSON string is again invalid.

With your method, you are also creating an invalid array, because you are adding a , after every object you add to the string, your final string for the array will look like the following [{...}, {...},] Which is not valid JSON (there may be some parsers accepting trailing commas, but strictly speaking it is not allowed)

Why are you even creating your JSON string by hand, just to parse it again a few lines of code later? Just fill your model directly ...

InputModel input = new InputModel {
  Files = new List<InputFile>()
};
foreach(string directory in directories) // Going through all directories
{                
    foreach (string filePath in Directory.GetFiles(directory)) // Adding every file to the Input Model List
    {
        string content = System.IO.File.ReadAllText(filePath);                    
        var inputfile = new InputFile {
          Content = content, 
          Path = filePath
        };
        input.Files.Add(inputfile);
    }
}
derpirscher
  • 14,418
  • 3
  • 18
  • 35