Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
DictionaryKeyPolicy not applied to keys that contain non primitive ty… (
Browse files Browse the repository at this point in the history
#41691)

* DictionaryKeyPolicy not applied to keys that contain non primitive types #41176

https://github.com/dotnet/corefx/issues/41176#event-2697607085

* #41176: DictionaryKeyPolicy not applied to keys that contain non primitive types

https://github.com/dotnet/corefx/issues/41176

* add unit tests

#41691

* Remove check for JsonExtensionDataAttribute to avoid reflection.
  • Loading branch information
marcnet80 authored and Jozkee committed Nov 14, 2019
1 parent c14fc56 commit d9dd0da
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
Expand Up @@ -81,8 +81,14 @@ public static partial class JsonSerializer
jsonPropertyInfo.GetDictionaryKeyAndValue(ref state.Current, out key, out value);
}

if (options.DictionaryKeyPolicy != null && state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing)
{
key = options.DictionaryKeyPolicy.ConvertName(key);
}

// An object or another enumerator requires a new stack frame.
state.Push(elementClassInfo, value);

state.Current.KeyName = key;
}

Expand Down
142 changes: 142 additions & 0 deletions src/System.Text.Json/tests/Serialization/DictionaryTests.KeyPolicy.cs
Expand Up @@ -258,5 +258,147 @@ public static void KeyConflict_Serialize_WriteAll()
// Check that we write all.
Assert.Equal(@"{""myInt"":1,""myInt"":2}", json);
}

[Fact]
public static void CamelCaseSerialize_ApplyDictionaryKeyPolicy()
{
const string JsonCamel = @"{""keyDict"":{""keyString"":""text"",""keyNumber"":1000,""keyBool"":true},""keyList"":[1,2,3]}";
var options = new JsonSerializerOptions
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
};

var obj = new Dictionary<string, object>();
obj["KeyDict"] = new Dictionary<string, object>()
{
{ "KeyString", "text" },
{ "KeyNumber", 1000 },
{ "KeyBool", true }
};
obj["KeyList"] = new List<int>() { 1, 2, 3 };

var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});

Assert.Equal(JsonCamel, json);
}

[Fact]
public static void SerializationWithJsonExtensionDataAttribute_IgoneDictionaryKeyPolicy()
{
var expectedJson = @"{""KeyInt"":1000,""KeyString"":""text"",""KeyBool"":true,""KeyObject"":{},""KeyList"":[],""KeyDictionary"":{}}";
var obj = new ClassWithExtensionDataProperty();
obj.Data = new Dictionary<string, object>()
{
{ "KeyInt", 1000 },
{ "KeyString", "text" },
{ "KeyBool", true },
{ "KeyObject", new object() },
{ "KeyList", new List<string>() },
{ "KeyDictionary", new Dictionary<string, string>() }
};
string json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
Assert.Equal(expectedJson, json);
}

private class ClassWithExtensionDataProperty
{
[JsonExtensionData]
public Dictionary<string, object> Data { get; set; }
}

[Fact]
public static void CamelCaseSerialize_ForTypedDictionary_ApplyDictionaryKeyPolicy()
{
const string JsonCamel = @"{""keyDict"":{""Name"":""text"",""Number"":1000,""isValid"":true,""Values"":[1,2,3]}}";
var obj = new Dictionary<string, CustomClass>()
{
{ "KeyDict", CreateCustomObject() }
};
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});

Assert.Equal(JsonCamel, json);
}

private class CustomClass
{
public string Name { get; set; }
public int Number { get; set; }
public bool isValid { get; set; }
public List<int> Values { get; set; }
}

private static CustomClass CreateCustomObject()
{
return new CustomClass { Name = "text", Number = 1000, isValid = true, Values = new List<int>() { 1, 2, 3 } };
}

[Fact]
public static void CamelCaseSerialize_ForNestedTypedDictionary_ApplyDictionaryKeyPolicy()
{
const string JsonCamel = @"{""keyDict"":{""nestedKeyDict"":{""Name"":""text"",""Number"":1000,""isValid"":true,""Values"":[1,2,3]}}}";
var options = new JsonSerializerOptions
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
};
var obj = new Dictionary<string, Dictionary<string, CustomClass>>(){
{ "KeyDict", new Dictionary<string,CustomClass>()
{{ "NestedKeyDict", CreateCustomObject() }}
}};
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});

Assert.Equal(JsonCamel, json);
}

private class TestClassWithDictionary
{
public Dictionary<string, CustomClass> Data { get; set; }
}

[Fact]
public static void CamelCaseSerialize_ForClassWithDictionaryProperty_ApplyDictionaryKeyPolicy()
{
const string JsonCamel = @"{""Data"":{""keyObj"":{""Name"":""text"",""Number"":1000,""isValid"":true,""Values"":[1,2,3]}}}";
var obj = new TestClassWithDictionary();
obj.Data = new Dictionary<string, CustomClass> {
{"KeyObj", CreateCustomObject() }
};
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});
Assert.Equal(JsonCamel, json);
}

[Fact]
public static void CamelCaseSerialize_ForKeyValuePairWithDictionaryValue_ApplyDictionaryKeyPolicy()
{
const string JsonCamel = @"{""Key"":""KeyPair"",""Value"":{""keyDict"":{""Name"":""text"",""Number"":1000,""isValid"":true,""Values"":[1,2,3]}}}";
var options = new JsonSerializerOptions
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
};
var obj = new KeyValuePair<string, Dictionary<string, CustomClass>>
("KeyPair", new Dictionary<string, CustomClass> {
{"KeyDict", CreateCustomObject() }
});
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions()
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase
});

Assert.Equal(JsonCamel, json);
}
}
}

0 comments on commit d9dd0da

Please sign in to comment.