Fixed json bom handling when serializing/deserializing json

This commit is contained in:
2026-06-01 14:46:03 +02:00
parent ae468e9f19
commit 076504753e
3 changed files with 56 additions and 4 deletions
@@ -1,4 +1,5 @@
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
@@ -6,6 +7,8 @@ namespace BizTalkPlatformManagementTool.Services
{
public static class JsonFileStore
{
private static readonly Encoding Utf8NoBom = new UTF8Encoding(false);
public static void Save<T>(string path, T value)
{
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
@@ -17,8 +20,8 @@ namespace BizTalkPlatformManagementTool.Services
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, value);
var json = Encoding.UTF8.GetString(stream.ToArray());
File.WriteAllText(path, json, Encoding.UTF8);
var json = Utf8NoBom.GetString(stream.ToArray());
File.WriteAllText(path, json, Utf8NoBom);
}
}
@@ -29,10 +32,55 @@ namespace BizTalkPlatformManagementTool.Services
UseSimpleDictionaryFormat = true
});
using (var stream = File.OpenRead(path))
var json = NormalizeJson(File.ReadAllText(path, Encoding.UTF8));
using (var stream = new MemoryStream(Utf8NoBom.GetBytes(json)))
{
return (T)serializer.ReadObject(stream);
try
{
return (T)serializer.ReadObject(stream);
}
catch (SerializationException ex)
{
throw new InvalidDataException("Failed to load JSON file '" + path + "'. " + DescribeJsonStart(json), ex);
}
}
}
private static string NormalizeJson(string json)
{
if (string.IsNullOrEmpty(json))
{
return json;
}
if (json[0] == '\uFEFF')
{
json = json.Substring(1);
}
if (json.StartsWith("\u00EF\u00BB\u00BF"))
{
json = json.Substring(3);
}
return json;
}
private static string DescribeJsonStart(string json)
{
if (string.IsNullOrWhiteSpace(json))
{
return "The file is empty or contains only whitespace.";
}
var trimmed = json.TrimStart();
var first = trimmed.Length == 0 ? '\0' : trimmed[0];
if (first != '{' && first != '[')
{
return "The first JSON character is '" + first + "' instead of '{' or '['.";
}
return "The file starts with valid JSON syntax but could not be deserialized into the expected model.";
}
}
}