public void ExtensionDataGetterCanBeIteratedMultipleTimes() { DefaultContractResolver resolver = new DefaultContractResolver(); JsonObjectContract contract = (JsonObjectContract)resolver.ResolveContract(typeof(ClassWithExtensionData)); ClassWithExtensionData myClass = new ClassWithExtensionData { Data = new Dictionary <string, object> { { "SomeField", "Field" }, } }; ExtensionDataGetter getter = contract.ExtensionDataGetter; IEnumerable <KeyValuePair <object, object> > dictionaryData = getter(myClass).ToDictionary(kv => kv.Key, kv => kv.Value); Assert.IsTrue(dictionaryData.Any()); Assert.IsTrue(dictionaryData.Any()); IEnumerable <KeyValuePair <object, object> > extensionData = getter(myClass); Assert.IsTrue(extensionData.Any()); Assert.IsTrue(extensionData.Any()); // second test fails if the enumerator returned isn't reset }
public static void ReadAheadFromRoot(int stringSize) { string json = CreateTestStringProperty(stringSize); var options = new JsonSerializerOptions(); options.Converters.Add(new ClassWithStringPropertyConverter()); // Ensure buffer size is small as possible for read-ahead. options.DefaultBufferSize = 1; byte[] data = Encoding.UTF8.GetBytes(json); { MemoryStream stream = new MemoryStream(data); ClassWithStringProperties obj = JsonSerializer.DeserializeAsync <ClassWithStringProperties>(stream, options).Result; VerifyClassWithStringProperties(obj, stringSize); string jsonSerialized = JsonSerializer.Serialize(obj, options); Assert.Equal(json, jsonSerialized); } { // Verify extension data works with read-ahead. Extension data stored on JsonElement which has a custom converter. MemoryStream stream = new MemoryStream(data); ClassWithExtensionData obj = JsonSerializer.DeserializeAsync <ClassWithExtensionData>(stream, options).Result; VerifyExtensionDataStringProperties(obj, stringSize); string jsonSerialized = JsonSerializer.Serialize(obj, options); Assert.Equal(json, jsonSerialized); } }
private static void ExtensionProperty_IgnoresCustomSerializerWithExplicitConverterInternal <TRoot, TDictionary, TOverflowItem>() where TRoot : IClassWithOverflow <TDictionary>, new() where TDictionary : IDictionary <string, TOverflowItem> { ClassWithExtensionData <TDictionary> obj = JsonSerializer.Deserialize <ClassWithExtensionData <TDictionary> >(@"{""TestKey"":""TestValue""}"); Assert.Equal("TestValue", ((JsonElement)(object)obj.Overflow["TestKey"]).GetString()); }
private static void ExtensionProperty_IgnoresCustomSerializerWithOptionsInternal <TDictionary, TOverflowItem, TConverter>() where TConverter : JsonConverter, new() where TDictionary : IDictionary <string, TOverflowItem> { var options = new JsonSerializerOptions(); options.Converters.Add(new TConverter()); ClassWithExtensionData <TDictionary> obj = JsonSerializer.Deserialize <ClassWithExtensionData <TDictionary> >(@"{""TestKey"":""TestValue""}", options); Assert.Equal("TestValue", ((JsonElement)(object)obj.Overflow["TestKey"]).GetString()); }
private static void VerifyExtensionDataStringProperties(ClassWithExtensionData obj, int stringSize) { // The 10 properties will cause buffer boundary cases where the converter requires read-ahead. Assert.Equal(new string('0', stringSize), ((JsonElement)obj.MyOverflow["MyString0"]).ToString()); Assert.Equal(new string('1', stringSize), ((JsonElement)obj.MyOverflow["MyString1"]).ToString()); Assert.Equal(new string('2', stringSize), ((JsonElement)obj.MyOverflow["MyString2"]).ToString()); Assert.Equal(new string('3', stringSize), ((JsonElement)obj.MyOverflow["MyString3"]).ToString()); Assert.Equal(new string('4', stringSize), ((JsonElement)obj.MyOverflow["MyString4"]).ToString()); Assert.Equal(new string('5', stringSize), ((JsonElement)obj.MyOverflow["MyString5"]).ToString()); Assert.Equal(new string('6', stringSize), ((JsonElement)obj.MyOverflow["MyString6"]).ToString()); Assert.Equal(new string('7', stringSize), ((JsonElement)obj.MyOverflow["MyString7"]).ToString()); Assert.Equal(new string('8', stringSize), ((JsonElement)obj.MyOverflow["MyString8"]).ToString()); Assert.Equal(new string('9', stringSize), ((JsonElement)obj.MyOverflow["MyString9"]).ToString()); }
public static void ReadAheadFromProperties(int stringSize) { string jsonProperties = CreateTestStringProperty(stringSize); StringBuilder builder = new StringBuilder(); builder.Append("{"); builder.Append(@"""Property1"":"); builder.Append(jsonProperties); builder.Append(@",""Property2"":"); builder.Append(jsonProperties); builder.Append(@",""Property3"":"); builder.Append(jsonProperties); builder.Append("}"); string json = builder.ToString(); var options = new JsonSerializerOptions(); options.Converters.Add(new ClassWithStringPropertyConverter()); // Ensure buffer size is small as possible for read-ahead. options.DefaultBufferSize = 1; byte[] data = Encoding.UTF8.GetBytes(json); { MemoryStream stream = new MemoryStream(data); ClassWithNoConverter obj = JsonSerializer.DeserializeAsync <ClassWithNoConverter>(stream, options).Result; VerifyClassWithStringProperties(obj.Property1, stringSize); VerifyClassWithStringProperties(obj.Property2, stringSize); VerifyClassWithStringProperties(obj.Property3, stringSize); string jsonSerialized = JsonSerializer.Serialize(obj, options); Assert.Equal(json, jsonSerialized); } { // Verify extension data works with read-ahead. Extension data stored on JsonElement which has a custom converter. MemoryStream stream = new MemoryStream(data); ClassWithExtensionData obj = JsonSerializer.DeserializeAsync <ClassWithExtensionData>(stream, options).Result; Assert.NotNull(obj.MyOverflow["Property1"]); Assert.NotNull(obj.MyOverflow["Property2"]); Assert.NotNull(obj.MyOverflow["Property3"]); string jsonSerialized = JsonSerializer.Serialize(obj, options); Assert.Equal(json, jsonSerialized); } }
public async Task IgnoreKeyPolicyForExtensionData() { var options = new JsonSerializerOptions { DictionaryKeyPolicy = JsonNamingPolicy.CamelCase // e.g. Key1 -> key1. }; // Ensure we ignore key policy for extension data and deserialize keys as they are. ClassWithExtensionData myClass = await JsonSerializerWrapperForString.DeserializeWrapper <ClassWithExtensionData>(@"{""Key1"":1, ""Key2"":2}", options); Assert.Equal(1, (myClass.ExtensionData["Key1"]).GetInt32()); Assert.Equal(2, (myClass.ExtensionData["Key2"]).GetInt32()); // Ensure we ignore key policy for extension data and serialize keys as they are. Assert.Equal(@"{""Key1"":1,""Key2"":2}", await JsonSerializerWrapperForString.SerializeWrapper(myClass, options)); }
public static void IgnoreKeyPolicyForExtensionData() { var options = new JsonSerializerOptions { DictionaryKeyPolicy = JsonNamingPolicy.CamelCase // e.g. Key1 -> key1. }; // Ensure we ignore key policy for extension data and deserialize keys as they are. ClassWithExtensionData myClass = JsonSerializer.Deserialize <ClassWithExtensionData>(@"{""Key1"":1, ""Key2"":2}", options); Assert.Equal(1, (myClass.ExtensionData["Key1"]).GetInt32()); Assert.Equal(2, (myClass.ExtensionData["Key2"]).GetInt32()); // Ensure we ignore key policy for extension data and serialize keys as they are. Assert.Equal(@"{""Key1"":1,""Key2"":2}", JsonSerializer.Serialize(myClass, options)); }
private static void ExtensionProperty_SupportsWritingToCustomSerializerWithOptionsInternal <TDictionary, TConverter>() where TDictionary : new() where TConverter : JsonConverter, new() { var root = new ClassWithExtensionData <TDictionary>() { Overflow = new TDictionary() }; var options = new JsonSerializerOptions(); options.Converters.Add(new TConverter()); string json = JsonSerializer.Serialize(root, options); Assert.Equal(@"{""MyCustomOverflowWrite"":""OverflowValueWrite""}", json); }
public async Task DictionaryKeyContainingLeadingDollarSignShouldBeEncoded() { //$ Key in dictionary holding primitive type. Dictionary <string, object> dictionary = new Dictionary <string, object> { ["$string"] = "Hello world" }; string json = await JsonSerializerWrapperForString.SerializeWrapper(dictionary, s_serializerOptionsPreserve); Assert.Equal(@"{""$id"":""1"",""\u0024string"":""Hello world""}", json); //$ Key in dictionary holding complex type. dictionary = new Dictionary <string, object> { ["$object"] = new ClassWithExtensionData { Hello = "World" } }; json = await JsonSerializerWrapperForString.SerializeWrapper(dictionary, s_serializerOptionsPreserve); Assert.Equal(@"{""$id"":""1"",""\u0024object"":{""$id"":""2"",""Hello"":""World""}}", json); //$ Key in ExtensionData dictionary var poco = new ClassWithExtensionData { ExtensionData = { ["$string"] = "Hello world", ["$object"] = new ClassWithExtensionData { Hello = "World" } } }; json = await JsonSerializerWrapperForString.SerializeWrapper(poco, s_serializerOptionsPreserve); Assert.Equal(@"{""$id"":""1"",""\u0024string"":""Hello world"",""\u0024object"":{""$id"":""2"",""Hello"":""World""}}", json); //TODO: //Extend the scenarios to also cover CLR and F# properties with a leading $. //Also add scenarios where a NamingPolicy (DictionaryKey or Property) appends the leading $. }