Search code examples
c#jsonminecraftwhitelist

Format values as a valid json file in C#


I'm trying to write lines in a valid JSON format using C# in a efficient way What the file should look like:

[
  {
    "uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
    "name": "thijmen321"
  },
  {
    "uuid": "3b90891d-e6fc-44cc-a1a8-e822378ec148",
    "name": "TehGTypo"
  },
  {
    "uuid": "5f820c39-5883-4392-b174-3125ac05e38c",
    "name": "CaptainSparklez"
  }
]

I already have the names and the UUIDs, but I need a way to write them to a file. I want to do this one by one, so, first the file looks like this:

[
  {
    "uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
    "name": "thijmen321"
  }
]

Then like this:

[
  {
    "uuid": "c92161ba-7571-3313-9b59-5c615d25251c",
    "name": "thijmen321"
  },
  {
    "uuid": "3b90891d-e6fc-44cc-a1a8-e822378ec148",
    "name": "TehGTypo"
  }
]

etc. But of course, the UUIDs and the names are different, so how can I do this in a efficient way without using any APIs etc.? My current (really inefficient) code:

public void addToWhitelist()
{
    if (String.IsNullOrEmpty(whitelistAddTextBox.Text)) return;
    string player = String.Empty;

    try
    {
        string url = String.Format("https://api.mojang.com/users/profiles/minecraft/{0}", whitelistAddTextBox.Text);
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url));
        request.Credentials = CredentialCache.DefaultCredentials;

        using (WebResponse response = request.GetResponse())
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            player = reader.ReadToEnd();
    }
    catch (WebException ex)
    {
        Extensions.ShowError("Cannot connect to http://api.mojang.com/! Check if you have a valid internet connection. Stacktrace: " + ex, MessageBoxIcon.Error);
    }
    catch (Exception ex)
    {
        Extensions.ShowError("An error occured! Stacktrace: " + ex, MessageBoxIcon.Error);
    }

    if (String.IsNullOrWhiteSpace(player)) { Extensions.ShowError("This player doesn't seem to exist.", MessageBoxIcon.Error); return; }
    player = player.Replace(",\"legacy\":true", "")
    .Replace("\"id", "    \"uuid")
    .Replace("\"name", "    \"name")
    .Replace(",", ",\n")
    .Replace("{", "  {\n")
    .Replace("}", "\n  },");

    File.WriteAllText(Program.programPath + @"\Servers\" + servers[currentIndex].Name + @"\whitelist.json", "");

    try
    {
        using (StreamWriter sw = File.AppendText(Program.programPath + @"\Servers\" + servers[currentIndex].Name + @"\whitelist.json"))
        {
            sw.WriteLine("[");
            foreach (string s in File.ReadAllLines(Program.programPath + @"\Servers\" + servers[currentIndex].Name + @"\whitelist.json"))
                if (s.Contains("[") || s.Contains("]") || s.Equals(Environment.NewLine)) continue;
                else sw.WriteLine(s);
            sw.WriteLine(player);
            sw.WriteLine("]");

            whitelistListBox.Items.Add("\n" + whitelistAddTextBox.Text);
        }
    }
    catch (Exception ex) { Extensions.ShowError("An error occured while update whitelist.json! Stacktrace: " + ex); }
    whitelistAddTextBox.Clear();
}

Solution

  • The recommand "Microsoft" way is with a data contract and the DataContractJsonSerializer.. see here

    https://msdn.microsoft.com/de-de/library/system.runtime.serialization.json.datacontractjsonserializer%28v=vs.110%29.aspx

    an example of the contact would be:

    [DataContract]
    internal class Person
    {
        [DataMember]
        internal string name;
    
        [DataMember]
        internal string Uuid ;
    }
    

    you use the class in the following way (obviously)

     Person p = new Person();
     p.name = "John";
     p.Uuid = "3b90891d-e6fc-44cc-a1a8-e822378ec148";
    

    and serialize it with the Contract Serializer

      MemoryStream stream1 = new MemoryStream();
      DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
    ser.WriteObject(stream1, p);
    

    example to show the serialzed data:

      stream1.Position = 0;
      StreamReader sr = new StreamReader(stream1);
      Console.WriteLine(sr.ReadToEnd());