using System.Text.Json; using System.Text.Json.Serialization; namespace FinalFactory.Rendezvous.Contracts; public static class ContractJson { private static readonly JsonSerializerOptions SharedOptions = CreateReadOnlyOptions(); public static JsonSerializerOptions Options => SharedOptions; public static JsonSerializerOptions CreateOptions() { JsonSerializerOptions options = new(JsonSerializerDefaults.Web); Configure(options); return options; } public static void Configure(JsonSerializerOptions options) { if (options is null) { throw new ArgumentNullException(nameof(options)); } options.AllowTrailingCommas = false; options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; // Nine is the minimum that lets ASP.NET generate the nullable fallback // OpenAPI schema; the 16 KiB HTTP body limit still bounds parser work. options.MaxDepth = 9; options.NumberHandling = JsonNumberHandling.Strict; options.PropertyNameCaseInsensitive = false; options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.ReadCommentHandling = JsonCommentHandling.Disallow; options.UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip; options.WriteIndented = false; if (!options.Converters.OfType().Any()) { options.Converters.Add( new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, allowIntegerValues: false)); } } private static JsonSerializerOptions CreateReadOnlyOptions() { JsonSerializerOptions options = CreateOptions(); options.MakeReadOnly(populateMissingResolver: true); return options; } }