public DataContract GetDataContractForType(Type type) { var underlyingType = type.IsNullable(out Type innerType) ? innerType : type; if (PrimitiveTypesAndFormats.ContainsKey(underlyingType)) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats[underlyingType]; return(new DataContract( dataType: primitiveTypeAndFormat.Item1, format: primitiveTypeAndFormat.Item2, underlyingType: underlyingType)); } if (underlyingType.IsEnum) { var enumValues = GetSerializedEnumValuesFor(underlyingType); var primitiveTypeAndFormat = (enumValues.Any(value => value is string)) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[underlyingType.GetEnumUnderlyingType()]; return(new DataContract( dataType: primitiveTypeAndFormat.Item1, format: primitiveTypeAndFormat.Item2, underlyingType: underlyingType, enumValues: enumValues)); } if (underlyingType.IsDictionary(out Type keyType, out Type valueType)) { if (keyType.IsEnum) { throw new NotSupportedException( $"Schema cannot be generated for type {underlyingType} as it's not supported by the System.Text.Json serializer"); } return(new DataContract( dataType: DataType.Object, underlyingType: underlyingType, additionalPropertiesType: valueType)); } if (underlyingType.IsEnumerable(out Type itemType)) { return(new DataContract( dataType: DataType.Array, underlyingType: underlyingType, arrayItemType: itemType)); } return(new DataContract( dataType: DataType.Object, underlyingType: underlyingType, properties: GetDataPropertiesFor(underlyingType, out Type extensionDataValueType), additionalPropertiesType: extensionDataValueType)); }
public DataContract GetDataContractForType(Type type) { if (type.IsOneOf(typeof(object), typeof(JsonDocument), typeof(JsonElement))) { return(DataContract.ForDynamic(underlyingType: type)); } if (PrimitiveTypesAndFormats.ContainsKey(type)) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats[type]; return(DataContract.ForPrimitive( underlyingType: type, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (type.IsEnum) { var enumValues = type.GetEnumValues(); //Test to determine if the serializer will treat as string var serializeAsString = (enumValues.Length > 0) && Serialize(enumValues.GetValue(0)).StartsWith("\""); var primitiveTypeAndFormat = serializeAsString ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[type.GetEnumUnderlyingType()]; return(DataContract.ForPrimitive( underlyingType: type, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (IsSupportedDictionary(type, out Type keyType, out Type valueType)) { return(DataContract.ForDictionary( underlyingType: type, keyType: keyType, valueType: valueType)); } if (IsSupportedCollection(type, out Type itemType)) { return(DataContract.ForArray( underlyingType: type, itemType: itemType)); } return(DataContract.ForObject( underlyingType: type, properties: GetDataPropertiesFor(type, out Type extensionDataType), extensionDataType: extensionDataType)); }
public DataContract GetDataContractForType(Type type) { if (type.IsOneOf(typeof(JsonDocument), typeof(JsonElement))) { return(DataContract.ForDynamic(underlyingType: type)); } if (PrimitiveTypesAndFormats.ContainsKey(type)) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats[type]; return(DataContract.ForPrimitive( underlyingType: type, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (type.IsEnum) { var enumValues = GetSerializedEnumValuesFor(type); var primitiveTypeAndFormat = (enumValues.Any(value => value is string)) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[type.GetEnumUnderlyingType()]; return(DataContract.ForPrimitive( underlyingType: type, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2, enumValues: enumValues)); } if (IsSupportedDictionary(type, out Type keyType, out Type valueType)) { return(DataContract.ForDictionary( underlyingType: type, valueType: valueType)); } if (IsSupportedCollection(type, out Type itemType)) { return(DataContract.ForArray( underlyingType: type, itemType: itemType)); } return(DataContract.ForObject( underlyingType: type, properties: GetDataPropertiesFor(type, out Type extensionDataType), extensionDataType: extensionDataType)); }
public SerializerContract GetSerializerContractForType(Type type) { var underlyingType = type.IsNullable(out Type innerType) ? innerType : type; if (PrimitiveTypesAndFormats.ContainsKey(underlyingType)) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats[underlyingType]; return(SerializerContract.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2)); } if (underlyingType.IsEnum) { var enumValues = GetSerializeEnumValuesFor(underlyingType); var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string))) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[underlyingType.GetEnumUnderlyingType()]; return(SerializerContract.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2, enumValues)); } if (underlyingType.IsDictionary(out Type keyType, out Type valueType)) { return(SerializerContract.ForDictionary(underlyingType, keyType, valueType)); } if (underlyingType.IsEnumerable(out Type itemType)) { return(SerializerContract.ForArray(underlyingType, itemType)); } return(SerializerContract.ForObject( underlyingType, GetSerializerPropertiesFor(underlyingType, out Type extensionDataValueType), extensionDataValueType)); }
public DataContract GetDataContractForType(Type type) { if (type.IsOneOf(typeof(object), typeof(JToken), typeof(JObject), typeof(JArray))) { return(DataContract.ForDynamic(underlyingType: type)); } var jsonContract = _contractResolver.ResolveContract(type); if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats.ContainsKey(jsonContract.UnderlyingType) ? PrimitiveTypesAndFormats[jsonContract.UnderlyingType] : Tuple.Create(DataType.String, (string)null); return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (jsonContract is JsonPrimitiveContract && jsonContract.UnderlyingType.IsEnum) { var enumValues = GetSerializedEnumValuesFor(jsonContract); var primitiveTypeAndFormat = (enumValues.Values.Any(value => value is string)) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()]; return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (jsonContract is JsonArrayContract jsonArrayContract) { return(DataContract.ForArray( underlyingType: jsonArrayContract.UnderlyingType, itemType: jsonArrayContract.CollectionItemType ?? typeof(object))); } if (jsonContract is JsonDictionaryContract jsonDictionaryContract) { 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 enumValues = GetSerializedEnumValuesFor(_contractResolver.ResolveContract(keyType)); keys = enumValues.Values.Any(value => value is string) ? enumValues.Cast <string>() : keyType.GetEnumNames(); } return(DataContract.ForDictionary( underlyingType: jsonDictionaryContract.UnderlyingType, keyType: keyType, valueType: valueType)); } if (jsonContract is JsonObjectContract jsonObjectContract) { string typeNameProperty = null; string typeNameValue = null; if (_serializerSettings.TypeNameHandling == TypeNameHandling.Objects || _serializerSettings.TypeNameHandling == TypeNameHandling.All || _serializerSettings.TypeNameHandling == TypeNameHandling.Auto) { typeNameProperty = "$type"; typeNameValue = (_serializerSettings.TypeNameAssemblyFormatHandling == TypeNameAssemblyFormatHandling.Full) ? jsonObjectContract.UnderlyingType.AssemblyQualifiedName : $"{jsonObjectContract.UnderlyingType.FullName}, {jsonObjectContract.UnderlyingType.Assembly.GetName().Name}"; } return(DataContract.ForObject( underlyingType: jsonObjectContract.UnderlyingType, properties: GetDataPropertiesFor(jsonObjectContract, out Type extensionDataType), extensionDataType: extensionDataType, typeNameProperty: typeNameProperty, typeNameValue: typeNameValue)); } return(DataContract.ForDynamic(underlyingType: type)); }
public DataContract GetDataContractForType(Type type) { var jsonContract = _contractResolver.ResolveContract(type.IsNullable(out Type innerType) ? innerType : type); if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats.ContainsKey(jsonContract.UnderlyingType) ? PrimitiveTypesAndFormats[jsonContract.UnderlyingType] : Tuple.Create(DataType.String, (string)null); return(new DataContract( dataType: primitiveTypeAndFormat.Item1, format: primitiveTypeAndFormat.Item2, underlyingType: jsonContract.UnderlyingType)); } if (jsonContract is JsonPrimitiveContract && jsonContract.UnderlyingType.IsEnum) { var enumValues = GetSerializedEnumValuesFor(jsonContract); var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string))) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()]; return(new DataContract( dataType: primitiveTypeAndFormat.Item1, format: primitiveTypeAndFormat.Item2, underlyingType: jsonContract.UnderlyingType, enumValues: enumValues)); } if (jsonContract is JsonDictionaryContract jsonDictionaryContract) { var keyType = jsonDictionaryContract.DictionaryKeyType ?? typeof(object); var valueType = jsonDictionaryContract.DictionaryValueType ?? typeof(object); if (keyType.IsEnum) { // This is a special case where we can include named properties based on the enum values var enumValues = GetDataContractForType(keyType).EnumValues; var propertyNames = enumValues.Any(value => value is string) ? enumValues.Cast <string>() : keyType.GetEnumNames(); return(new DataContract( dataType: DataType.Object, underlyingType: jsonDictionaryContract.UnderlyingType, properties: propertyNames.Select(name => new DataProperty(name, valueType)))); } return(new DataContract( dataType: DataType.Object, underlyingType: jsonDictionaryContract.UnderlyingType, additionalPropertiesType: valueType)); } if (jsonContract is JsonArrayContract jsonArrayContract) { return(new DataContract( dataType: DataType.Array, underlyingType: jsonArrayContract.UnderlyingType, arrayItemType: jsonArrayContract.CollectionItemType ?? typeof(object))); } if (jsonContract is JsonObjectContract jsonObjectContract) { return(new DataContract( dataType: DataType.Object, underlyingType: jsonObjectContract.UnderlyingType, properties: GetDataPropertiesFor(jsonObjectContract), additionalPropertiesType: jsonObjectContract.ExtensionDataValueType)); } if (jsonContract.UnderlyingType == typeof(JArray)) { return(new DataContract( dataType: DataType.Array, underlyingType: jsonContract.UnderlyingType, arrayItemType: typeof(JToken))); } if (jsonContract.UnderlyingType == typeof(JObject)) { return(new DataContract( dataType: DataType.Object, underlyingType: jsonContract.UnderlyingType)); } return(new DataContract( dataType: DataType.Unknown, underlyingType: jsonContract.UnderlyingType)); }
public DataContract GetDataContractForType(Type type) { if (type.IsAssignableTo(typeof(JToken))) { return(DataContract.ForDynamic(underlyingType: type)); } var jsonContract = _contractResolver.ResolveContract(type); if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats.ContainsKey(jsonContract.UnderlyingType) ? PrimitiveTypesAndFormats[jsonContract.UnderlyingType] : Tuple.Create(DataType.String, (string)null); return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2)); } if (jsonContract is JsonPrimitiveContract && jsonContract.UnderlyingType.IsEnum) { var enumValues = GetSerializedEnumValuesFor(jsonContract); var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string))) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()]; return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2, enumValues: enumValues)); } if (jsonContract is JsonArrayContract jsonArrayContract) { return(DataContract.ForArray( underlyingType: jsonArrayContract.UnderlyingType, itemType: jsonArrayContract.CollectionItemType ?? typeof(object))); } if (jsonContract is JsonDictionaryContract jsonDictionaryContract) { 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 enumValues = GetSerializedEnumValuesFor(_contractResolver.ResolveContract(keyType)); keys = enumValues.Any(value => value is string) ? enumValues.Cast <string>() : keyType.GetEnumNames(); } return(DataContract.ForDictionary( underlyingType: jsonDictionaryContract.UnderlyingType, valueType: valueType, keys: keys)); } if (jsonContract is JsonObjectContract jsonObjectContract) { return(DataContract.ForObject( underlyingType: jsonObjectContract.UnderlyingType, properties: GetDataPropertiesFor(jsonObjectContract), extensionDataType: jsonObjectContract.ExtensionDataValueType)); } return(DataContract.ForDynamic(underlyingType: type)); }
public DataContract GetDataContractForType(Type type) { if (type.IsOneOf(typeof(object), typeof(JToken), typeof(JObject), typeof(JArray))) { return(DataContract.ForDynamic( underlyingType: type, jsonConverter: JsonConverterFunc)); } var jsonContract = _contractResolver.ResolveContract(type); if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats.ContainsKey(jsonContract.UnderlyingType) ? PrimitiveTypesAndFormats[jsonContract.UnderlyingType] : Tuple.Create(DataType.String, (string)null); return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2, jsonConverter: JsonConverterFunc)); } if (jsonContract is JsonPrimitiveContract && jsonContract.UnderlyingType.IsEnum) { var enumValues = jsonContract.UnderlyingType.GetEnumValues(); //Test to determine if the serializer will treat as string var serializeAsString = (enumValues.Length > 0) && JsonConverterFunc(enumValues.GetValue(0)).StartsWith("\""); var primitiveTypeAndFormat = serializeAsString ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()]; return(DataContract.ForPrimitive( underlyingType: jsonContract.UnderlyingType, dataType: primitiveTypeAndFormat.Item1, dataFormat: primitiveTypeAndFormat.Item2, jsonConverter: JsonConverterFunc)); } if (jsonContract is JsonArrayContract jsonArrayContract) { return(DataContract.ForArray( underlyingType: jsonArrayContract.UnderlyingType, itemType: jsonArrayContract.CollectionItemType ?? typeof(object), jsonConverter: JsonConverterFunc)); } if (jsonContract is JsonDictionaryContract jsonDictionaryContract) { 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(); } return(DataContract.ForDictionary( underlyingType: jsonDictionaryContract.UnderlyingType, valueType: valueType, keys: keys, jsonConverter: JsonConverterFunc)); } if (jsonContract is JsonObjectContract jsonObjectContract) { string typeNameProperty = null; string typeNameValue = null; if (_serializerSettings.TypeNameHandling == TypeNameHandling.Objects || _serializerSettings.TypeNameHandling == TypeNameHandling.All || _serializerSettings.TypeNameHandling == TypeNameHandling.Auto) { typeNameProperty = "$type"; typeNameValue = (_serializerSettings.TypeNameAssemblyFormatHandling == TypeNameAssemblyFormatHandling.Full) ? jsonObjectContract.UnderlyingType.AssemblyQualifiedName : $"{jsonObjectContract.UnderlyingType.FullName}, {jsonObjectContract.UnderlyingType.Assembly.GetName().Name}"; } return(DataContract.ForObject( underlyingType: jsonObjectContract.UnderlyingType, properties: GetDataPropertiesFor(jsonObjectContract, out Type extensionDataType), extensionDataType: extensionDataType, typeNameProperty: typeNameProperty, typeNameValue: typeNameValue, jsonConverter: JsonConverterFunc)); } return(DataContract.ForDynamic( underlyingType: type, jsonConverter: JsonConverterFunc)); }
public SerializerMetadata GetSerializerMetadataForType(Type type) { var jsonContract = _contractResolver.ResolveContract(type.IsNullable(out Type innerType) ? innerType : type); if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum) { var primitiveTypeAndFormat = PrimitiveTypesAndFormats.ContainsKey(jsonContract.UnderlyingType) ? PrimitiveTypesAndFormats[jsonContract.UnderlyingType] : Tuple.Create("string", (string)null); return(SerializerMetadata.ForPrimitive(jsonContract.UnderlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2)); } if (jsonContract is JsonPrimitiveContract && jsonContract.UnderlyingType.IsEnum) { var enumValues = GetSerializerEnumValuesFor(jsonContract); var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string))) ? PrimitiveTypesAndFormats[typeof(string)] : PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()]; return(SerializerMetadata.ForPrimitive(jsonContract.UnderlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2, enumValues)); } if (jsonContract is JsonDictionaryContract jsonDictionaryContract) { var keyType = jsonDictionaryContract.DictionaryKeyType ?? typeof(object); var valueType = jsonDictionaryContract.DictionaryValueType ?? typeof(object); return(SerializerMetadata.ForDictionary(jsonDictionaryContract.UnderlyingType, keyType, valueType)); } if (jsonContract is JsonArrayContract jsonArrayContract) { var itemType = jsonArrayContract.CollectionItemType ?? typeof(object); return(SerializerMetadata.ForArray(jsonArrayContract.UnderlyingType, itemType)); } if (jsonContract is JsonObjectContract jsonObjectContract) { return(SerializerMetadata.ForObject( jsonContract.UnderlyingType, GetSerializerPropertiesFor(jsonObjectContract), jsonObjectContract.ExtensionDataValueType)); } if (jsonContract is JsonLinqContract jsonLinqContract) { if (jsonLinqContract.UnderlyingType == typeof(JArray)) { return(SerializerMetadata.ForArray(typeof(JArray), typeof(JToken))); } if (jsonLinqContract.UnderlyingType == typeof(JObject)) { return(SerializerMetadata.ForObject(typeof(JObject))); } } return(SerializerMetadata.ForDynamic(jsonContract.UnderlyingType)); }