I've written some code which has to read through 5,000 JSON files and replace a number which appears twice in each file. It's set to create a new json file and delete the old one, with that, other data must be transferred into the new file too, which is not a problem, however we have a list called attributes
that contain some text that use single quotes (for punctuation.) - however when the new json file is written, the text with the single quotes is changed and the single quote is replaced with \u0027
Example: old file contains:"0.png"
and "Hen's Secret Bra"
which in the new file is changing to "5000.png"
correct, and "Hen\u0027s Secret Bra"
incorrect. How do I transfer the single quote over properly?
Here is my code:
using System.Text.Json;
using System.Web;
internal class Program
{
private static void Main(string[] args)
{
//get all the json files
var jsonPath = @"/Users/jasonnienaber/Desktop/nft/cef/official/fatJSONselfFIX/test";
var jsonFiles = Directory.GetFiles(jsonPath, "*.json");
//loop through each file and process according to specs
foreach(var jsonFile in jsonFiles)
{
var json = File.ReadAllText(jsonFile);
var sample = JsonSerializer.Deserialize<Sample>(json);
var sampleNew = new SampleNew();
var intCounter = 0;
var newIntCounter = intCounter 5000;
var Counter = intCounter.ToString();
var newCounter = newIntCounter.ToString();
sampleNew.image = sample.image.Replace(Counter, newCounter);
sampleNew.name = sample.name.Replace(Counter, newCounter);
sampleNew.description = sample.description;
sampleNew.external_url = sample.external_url;
sampleNew.attributes = sample.attributes;
// serialize JSON to a string and then write string to a file
File.Delete(jsonFile);
File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew));
intCounter ;
}
}
public class Attribute
{
public string trait_type { get; set; }
public string value { get; set; }
}
public class Sample
{
// public string dna { get; set; }
public string image { get; set; }
public string name { get; set; }
public string description { get; set; }
public string external_url { get; set; }
public List<Attribute> attributes { get; set; }
public string compiler { get; set; }
}
public class SampleNew
{
public string image { get; set; }
public string name { get; set; }
public string description { get; set; }
public string external_url { get; set; }
//public List<Attribute> attributes { get; set; }
public List<Attribute> attributes {get; set;}
}
}
The "Hen's Secret Bra"
is within attributes
CodePudding user response:
Like Jon Skeet mentioned, it's valid to use \u0027
, however, you can change the serializer encoding options:
using System.Text.Json;
var obj = new
{
Name = "John's awesome object",
Age = 31
};
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
// writes obj to json file
File.WriteAllText("obj.json", JsonSerializer.Serialize(obj, options));
Outputs
{"Name":"John's awesome object","Age":31}
So in your code, you can do as follows:
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
//loop through each file and process according to specs
foreach (var jsonFile in jsonFiles)
{
var json = File.ReadAllText(jsonFile);
var sample = JsonSerializer.Deserialize<Sample>(json);
var sampleNew = new SampleNew();
var intCounter = 0;
var newIntCounter = intCounter 5000;
var Counter = intCounter.ToString();
var newCounter = newIntCounter.ToString();
sampleNew.image = sample.image.Replace(Counter, newCounter);
sampleNew.name = sample.name.Replace(Counter, newCounter);
sampleNew.description = sample.description;
sampleNew.external_url = sample.external_url;
sampleNew.attributes = sample.attributes;
// serialize JSON to a string and then write string to a file
File.Delete(jsonFile);
// use serializer options
File.WriteAllText(jsonFile, JsonSerializer.Serialize(sampleNew, options));
intCounter ;
}
CodePudding user response:
It is better to use Newtonsoft.Json to avoid any problems like this one.
But one of the thing you can try to fix an issue is to use a serialize options
var options = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
but it is unsafe
Another option is more awkward but more safe, since it affects only one symbol, not any as in the first case
var attr= new Attribute{trait_type="trait_type", value="Hen's Secret Bra"};
attr.value=attr.value.Replace("'","==="); //or you can try something else if you don't like ===
var json=System.Text.Json.JsonSerializer.Serialize(attr);
json=json.Replace("===","'");
File.WriteAllText(jsonFile, json);
json = File.ReadAllText(jsonFile);
result
{"trait_type":"trait_type","value":"Hen's Secret Bra"}