Home > database >  C# reading and writing a JSON file with a list of objects
C# reading and writing a JSON file with a list of objects

Time:09-11

I am currently trying quite desperately to process a JSON file with C#. In my case, that means reading in this file, adding another object to it, and then saving it again.

Here is the file:

[
  {
    "dwarfmaster": "Lorem ipsum dolor sit amet"
  },
  {
    "dwarfmaster": "Lorem ipsum dolor"
  },
  {
    "dwarfmaster": "Lorem ipsum dolor sit amet"
  },
  {
    "dwarfmaster": "Lorem ipsum dolor"
  }
]

i have to use Newtonsoft in any case, because other libraries are not allowed in the project.

Here is what I have incomplete so far:

string msg="something";
var chatFile = $"../chat.json";
var chat = new List<Dictionary<string, string>>();

if (File.Exists(chatFile))
{
    var chatJson = JArray.Parse(File.ReadAllText(chatFile));
    if (chatJson != null)
    {
        foreach (var item in chatJson)
        {
           // what to do here?
        }
    }
}

chat.Add(new Dictionary<string, string>() { { playername, msg } });

while (chat.Count > 30)
{
    chat.RemoveAt(0);
}

File.WriteAllText(chatFile, JsonConvert.SerializeObject(chat, Formatting.Indented));

I have virtually no experience with C# and come more from the php world, where the processing of JSON is much easier, and I'm sure for my problem there is also in C# a simple solution but I do not get it. Would be very happy about the help of experts.

UPDATE: Add a class to Project:

public class ChatElement
{
    public string name;
    public string text;

and then:

string msg="something";
var chatFile = $"../chat.json";
var chat = new List<Dictionary<string, string>>();

if (File.Exists(chatFile))
{
    var chat = new List<ChatElement>();
if (File.Exists(chatFile))
{
    chat = JsonConvert.DeserializeObject<List<ChatElement>>(File.ReadAllText(chatFile));
    if (chat != null)
    {
        chat.Add(new ChatElement() { name = _cInfo.playerName, text = _msg });
    }
}

while (chat.Count > 30)
{
    chat.RemoveAt(0);
}
File.WriteAllText(chatFile, JsonConvert.SerializeObject(chat, Formatting.Indented));

CodePudding user response:

I would suggest strongly typing your model instead of trying to append a dictionary. You can use the StreamReader and StreamWriter to read/write strings respectively, and then JsonConvert methods to Deserialize/Serialize your object. The process would look something like the following:

// Create models for your json structure
class Chat
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("text")]
    public string Text { get; set; }
}

// Read json from file
using (var sr = new StreamReader(chatFile));
var json = sr.ReadToEnd();
// Deserialize json into model
var chats = JsonConvert.DeserializeObject<IList<Chat>>(json);
// Append item to list
chats.Add(new Chat() { name = _cInfo.playerName, text = _msg });
// Write json back to file
using (var sw = new StreamWriter(chatFile));
sw.Write(JsonConvert.SerializeObject(chats));

CodePudding user response:

you can use a Dictionary, but since a key of Dictionary should be unique, you will have to create a new Dictionary object for each line of your chat, I don't think that it is a good idea. I would use something like this

   
if (File.Exists(chatFile))
{
   var json = File.ReadAllText(chatFile);
   List<ChatElement> chat = JArray.Parse(json)
                             .Select(c => ((JObject)c).Properties().First())
                             .Select(i => new ChatElement { name = i.Name, text = (string)i.Value })
                             .ToList();

    if (chat != null)
    {
        chat.Add(new ChatElement() { name = _cInfo.playerName, text = _msg });
    }

    while (chat.Count > 30)
    chat.RemoveAt(0);

    json = new JArray(chat.Select(i => new JObject { [i.name] = i.text })).ToString();

    File.WriteAllText(chatFile, json);

}
  • Related