I'm currently working on a big API Project and my task is, to make our JSON-Output canonical (No Whitespaces/Linebrakes and keys/values sorted in alphabetical order).
I've already managed to override the ContractResolver to sort the keys alphabetically, but its still missing the ordering of the values. The whitespaces get removed already and the other canonical factors are already done.
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList();
}
My two questions are:
Where to I apply the overwritten ContractResolver, so that it actually applies? I've already added it to the startup like this, but it doesnt affect my output.
services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CanonicalContractResolver(); });
or like this in my TestMethod, but it still doesnt work.
public void writeCanonicalJsonTest_Ok() { Assert.IsNotNull(policyConverter); var policy = new PrivacyPolicy() { Version = "1.2", Languages = new Languages() { LanguageList = new List<Language>() { new Language() { LanguageOption = LanguageOption.En, Name = "Terms of Service", Url = "https://example.org/somewhere/terms-2.0-en.html" }, new Language() { LanguageOption = LanguageOption.Fr, Name = "Conditions d'utilisation", Url = "https://example.org/somewhere/terms-2.0-fr.html" } } } }; var settings = new JsonSerializerSettings(); settings.Converters.Add(new PolicyConverter()); settings.ContractResolver = new CanonicalContractResolver(); var result = JsonConvert.SerializeObject(policy, typeof(Policy), settings); var test = JsonConvert.DeserializeObject<Policy>(result, settings); var noWhite = "{\"en\":{\"name\":\"Terms of Service\",\"url\":\"https://example.org/somewhere/terms-2.0-en.html\"},\"fr\":{" + "\"name\":\"Conditions d'utilisation\",\"url\":\"https://example.org/somewhere/terms-2.0-fr.html\"},\"version\":\"1.2\"}}"; if (test == null) { throw new ArgumentNullException("Result must have a value"); } Assert.IsNotNull(test); Assert.AreEqual(policy.Version, test.Version); Assert.IsNotNull(test.Languages); Assert.IsNotNull(test.Languages.LanguageList); Assert.AreEqual(policy.Languages.LanguageList[0].LanguageOption, test.Languages.LanguageList[0].LanguageOption); Assert.AreEqual(policy.Languages.LanguageList[0].Name, test.Languages.LanguageList[0].Name); Assert.AreEqual(policy.Languages.LanguageList[0].Url, test.Languages.LanguageList[0].Url); Assert.AreEqual(policy.Languages.LanguageList[1].LanguageOption, test.Languages.LanguageList[1].LanguageOption); Assert.AreEqual(policy.Languages.LanguageList[1].Name, test.Languages.LanguageList[1].Name); Assert.AreEqual(policy.Languages.LanguageList[1].Url, test.Languages.LanguageList[1].Url); Assert.AreEqual(noWhite, result); }
How do I additionally to sorting by keys, also sort by values?
Those two are actually so easy, but the documentation of newtonsoft is very sparce and I cant find any solutions after more then 8hrs of searching - really frustrating.
Thanks in advance for your help!