Skip to content

Commit

Permalink
Newtonsoft schemas: prioritize dictionary and array types just before…
Browse files Browse the repository at this point in the history
… object type
  • Loading branch information
Havunen committed Apr 13, 2024
1 parent c7e2e5f commit d2f75d2
Showing 1 changed file with 32 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ public DataContract GetDataContractForType(Type type)
jsonConverter: JsonConverterFunc);
}

if (JsonSerializerDataContractResolver.IsSupportedDictionary(type, out Type _, out Type valueType1))
if (jsonContract is JsonDictionaryContract jsonDictionaryContract)
{
var keyType = jsonDictionaryContract.DictionaryKeyType ?? typeof(object);
var valueType = jsonDictionaryContract.DictionaryValueType ?? typeof(object);

var keys = readDictionaryKeyTypes(keyType);

return DataContract.ForDictionary(
underlyingType: type,
valueType: valueType1,
keys: null, // STJ doesn't currently support dictionaries with enum key types
underlyingType: jsonDictionaryContract.UnderlyingType,
valueType: valueType,
keys: keys,
jsonConverter: JsonConverterFunc);
}

Expand All @@ -89,28 +94,13 @@ public DataContract GetDataContractForType(Type type)
jsonConverter: JsonConverterFunc);
}

if (jsonContract is JsonDictionaryContract jsonDictionaryContract)
if (JsonSerializerDataContractResolver.IsSupportedDictionary(type, out Type keyType1, out Type valueType1))
{
var keyType = jsonDictionaryContract.DictionaryKeyType ?? typeof(object);
var valueType = jsonDictionaryContract.DictionaryValueType ?? typeof(object);

IEnumerable<string> keys = null;

if (keyType.IsEnum)
{
// This is a special case where we know the possible key values
var enumValuesAsJson = keyType.GetEnumValues()
.Cast<object>()
.Select(value => JsonConverterFunc(value));

keys = enumValuesAsJson.Any(json => json.StartsWith("\""))
? enumValuesAsJson.Select(json => json.Replace("\"", string.Empty))
: keyType.GetEnumNames();
}
var keys = readDictionaryKeyTypes(keyType1);

return DataContract.ForDictionary(
underlyingType: jsonDictionaryContract.UnderlyingType,
valueType: valueType,
underlyingType: type,
valueType: valueType1,
keys: keys,
jsonConverter: JsonConverterFunc);
}
Expand Down Expand Up @@ -145,6 +135,25 @@ public DataContract GetDataContractForType(Type type)
jsonConverter: JsonConverterFunc);
}

private IEnumerable<string> readDictionaryKeyTypes(Type keyType)
{
IEnumerable<string> keys = null;

if (keyType.IsEnum)
{
// This is a special case where we know the possible key values
var enumValuesAsJson = keyType.GetEnumValues()
.Cast<object>()
.Select(value => JsonConverterFunc(value));

keys = enumValuesAsJson.Any(json => json.StartsWith("\""))
? enumValuesAsJson.Select(json => json.Replace("\"", string.Empty))
: keyType.GetEnumNames();
}

return keys;
}

private string JsonConverterFunc(object value)
{
return JsonConvert.SerializeObject(value, _serializerSettings);
Expand Down

0 comments on commit d2f75d2

Please sign in to comment.