2394425147
2394425147

Reputation: 13

How to encode text using File.WriteAllLines?

I was trying to make a txt file, then rename the extension to .json, I have the encoding step and the WriteAllLines step done, but how do I encode the text?(I have the string needed to write)

Here's the code

string[] lines = { "{", "\"version\": 1,", "\"schema_version\": 2,", "", 
    $"\"id\": \"{textBox14.Text}\",", "", $"\"title\": \"{textBox7.Text}\",", 
    $"\"title_localized\": \"{textBox18.Text}\",", "", $"\"artist\": \"{textBox6.Text}\",", 
    $"\"artist_localized\": \"{textBox8.Text}\",", $"\"artist_source\": \"{textBox9.Text}\",", 
    $"", $"\"illustrator\": \"{textBox10.Text}\",", $"\"illustrator_source\": \"{textBox11.Text}\",", 
    $"", $"\"charter\": \"{textBox13.Text}\",", $"", "\"music\": {", 
    $"\"path\": \"{textBox4.Text}\"", "}", "\"music_preview\": {", $"\"path\": \"{textBox5.Text}\"", "}", 
    "\"background\": {", $"\"path\": \"{open3.FileName}\"", "}", 
    "\"charts\": [", "{", "\"type\": \"easy\",", $"\"name\": \"{textBox15.Text}\",", 
    $"\"difficulty\": {numericUpDown1.Value},", $"\"path\": \"textBox1.Text\"", "},", 
    "{", "\"type\": \"hard\",", $"\"name\": \"{textBox16.Text}\",", $"\"difficulty\": {numericUpDown2.Value},", 
    $"\"path\": \"{textBox2.Text}\"", "},", $"]", $"", "}" };

Encoding utf8WithoutBom = new UTF8Encoding(true);

File.WriteAllLines($@"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines);

It was supposed to be something like this: https://cytoid.io/level.json

Upvotes: 0

Views: 434

Answers (1)

ProgrammingLlama
ProgrammingLlama

Reputation: 38767

Short answer:

Change this:

File.WriteAllLines($@"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines);

to this:

File.WriteAllLines($@"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", lines, utf8WithoutBom);

Long answer:

You shouldn't be generating JSON like this; you should be using a dedicated serializer. With your current solution, if a user enters an invalid character, your JSON will immediately become invalid. So, as a solution you could use Newtonsoft's JSON.Net. Here is an example:

Class definitions

public class Item
{
    public int Version { get; set; }
    public int SchemaVersion { get; set; }
    public string Id { get; set; }
    public string Title { get; set; }
    public string TitleLocalized { get; set; }
    public string Artist { get; set; }
    public string ArtistLocalized { get; set; }
    public string ArtistSource { get; set; }
    public string Illustrator { get; set; }
    public string IllustratorSource { get; set; }
    public string Charter { get; set; }
    public ItemMusic Music { get; set; }
    public ItemMusicPreview MusicPreview { get; set; }
    public ItemBackground Background { get; set; }
    public List<ItemChart> Charts { get; set; }
}

public class ItemMusic
{
    public string Path { get; set; }
}

public class ItemMusicPreview
{
    public string Path { get; set; }
}

public class ItemBackground
{
    public string Path { get; set; }
}

public class ItemChart
{
    public string Type { get; set; }
    public string Name { get; set; }
    public int Difficulty { get; set; }
    public string Path { get; set; }
}

Object initialization and serialization

var item = new Item
{
    Version = 1,
    SchemaVersion = 2,
    Id = textBox14.Text,
    Title = textBox7.Text,
    TitleLocalized = textBox18.Text,
    Artist = textBox6.Text,
    ArtistLocalized = textBox8.Text,
    ArtistSource = textBox9.Text,
    Illustrator = textBox10.Text,
    IllustratorSource = textBox11.Text,
    Charter = textBox13.Text,
    Music = new ItemMusic
    {
        Path = textBox4.Text
    },
    MusicPreview = new ItemMusicPreview
    {
        Path = textBox5.Text
    },
    Background = new ItemBackground
    {
        Path = open3.FileName
    },
    Charts = new List<ItemChart>
    {
        new ItemChart
        {
            Type = "easy",
            Name = textBox15.Text,
            Difficulty = numericUpDown1.Value,
            Path = textBox1.Text
        },
        new ItemChart
        {
            Type = "hard",
            Name = textBox16.Text,
            Difficulty = numericUpDown2.Value,
            Path = textBox2.Text
        }
    }
};

var settings = new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    }
};
var json = JsonConvert.SerializeObject(item, settings);
File.WriteAllText($@"C:\Users\Public\Desktop\level files\{textBox14.Text}\level.json", json, new UTF8Encoding(true));

You could also use an anonymous type instead of creating the full class definition, of course:

var item = new {
    Version = 1,
    SchemaVersion = 2,
    Charts = new List<object>
    {
        new {
            Type = "easy"
        }
    }
}

and then just serialize this.

Upvotes: 1

Related Questions