public DataContract GetDataContractForType(Type type) { if (!_messageTypeMapping.TryGetValue(type, out var messageDescriptor)) { if (typeof(IMessage).IsAssignableFrom(type)) { var property = type.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static); messageDescriptor = property?.GetValue(null) as MessageDescriptor; if (messageDescriptor == null) { throw new InvalidOperationException($"Couldn't resolve message descriptor for {type}."); } _messageTypeMapping[type] = messageDescriptor; } } if (messageDescriptor != null) { return(ConvertMessage(messageDescriptor)); } if (type.IsEnum) { if (_enumTypeMapping.TryGetValue(type, out var enumDescriptor)) { var values = enumDescriptor.Values.Select(v => v.Name).ToList(); //return new DataContract(DataType.String, type, enumValues: values); return(DataContract.ForPrimitive(type, DataType.String, null, enumValues: values)); } } return(_innerContractResolver.GetDataContractForType(type)); }
public DataContract GetDataContractForType(Type type) { if (!_messageTypeMapping.TryGetValue(type, out var messageDescriptor)) { if (typeof(IMessage).IsAssignableFrom(type)) { var property = type.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static); messageDescriptor = property?.GetValue(null) as MessageDescriptor; if (messageDescriptor == null) { throw new InvalidOperationException($"Couldn't resolve message descriptor for {type}."); } _messageTypeMapping[type] = messageDescriptor; } } if (messageDescriptor != null) { return(ConvertMessage(messageDescriptor)); } if (type.IsEnum) { if (_enumTypeMapping.TryGetValue(type, out var enumDescriptor)) { var values = enumDescriptor.Values.Select(v => v.Name).ToList(); return(DataContract.ForPrimitive(type, DataType.String, dataFormat: null, value => { var match = enumDescriptor.Values.SingleOrDefault(v => v.Number == (int)value); var name = match?.Name ?? value.ToString(); return @"""" + name + @""""; })); } } return(_innerContractResolver.GetDataContractForType(type)); }
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) { 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 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("string", (string)null); return(DataContract.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(DataContract.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(DataContract.ForDictionary(jsonDictionaryContract.UnderlyingType, keyType, valueType)); } if (jsonContract is JsonArrayContract jsonArrayContract) { var itemType = jsonArrayContract.CollectionItemType ?? typeof(object); return(DataContract.ForArray(jsonArrayContract.UnderlyingType, itemType)); } if (jsonContract is JsonObjectContract jsonObjectContract) { return(DataContract.ForObject( jsonContract.UnderlyingType, GetSerializerMembersFor(jsonObjectContract), jsonObjectContract.ExtensionDataValueType)); } if (jsonContract is JsonLinqContract jsonLinqContract) { if (jsonLinqContract.UnderlyingType == typeof(JArray)) { return(DataContract.ForArray(typeof(JArray), typeof(JToken))); } if (jsonLinqContract.UnderlyingType == typeof(JObject)) { return(DataContract.ForObject(typeof(JObject))); } } return(DataContract.ForDynamic(jsonContract.UnderlyingType)); }
private DataContract ConvertMessage(MessageDescriptor messageDescriptor) { if (IsWellKnownType(messageDescriptor)) { if (IsWrapperType(messageDescriptor)) { var field = messageDescriptor.Fields[Int32Value.ValueFieldNumber]; return(_innerContractResolver.GetDataContractForType( MessageDescriptorHelpers.ResolveFieldType(field))); } if (messageDescriptor.FullName == Timestamp.Descriptor.FullName || messageDescriptor.FullName == Duration.Descriptor.FullName || messageDescriptor.FullName == FieldMask.Descriptor.FullName) { //new DataContract(DataType.String, messageDescriptor.ClrType); return(DataContract.ForPrimitive(messageDescriptor.ClrType, DataType.String, null)); } } if (messageDescriptor.FullName == Struct.Descriptor.FullName) { //var anyProperties = new List<DataProperty> //{ // new DataProperty("@type", typeof(Value), true) //}; // new DataContract(DataType.Object, messageDescriptor.ClrType,additionalPropertiesType: typeof(Value)); return(DataContract.ForObject(messageDescriptor.ClrType, Array.Empty <DataProperty>(), typeof(Value))); } if (messageDescriptor.FullName == ListValue.Descriptor.FullName) { //return new DataContract(DataType.Array, messageDescriptor.ClrType, arrayItemType: typeof(Value)); return(DataContract.ForArray(messageDescriptor.ClrType, itemType: typeof(Value))); } if (messageDescriptor.FullName == Value.Descriptor.FullName) { //return new DataContract(DataType.Unknown, messageDescriptor.ClrType); //return DataContract.ForDynamic(messageDescriptor.ClrType); return(DataContract.ForPrimitive(messageDescriptor.ClrType, DataType.Unknown, dataFormat: null)); } if (messageDescriptor.FullName == Any.Descriptor.FullName) { var anyProperties = new List <DataProperty> { new DataProperty("@type", typeof(string), true) }; // return new DataContract(DataType.Object, messageDescriptor.ClrType, properties: anyProperties, additionalPropertiesType: typeof(Value)); return(DataContract.ForObject(messageDescriptor.ClrType, properties: anyProperties, extensionDataType: typeof(Value))); } var properties = new List <DataProperty>(); foreach (var field in messageDescriptor.Fields.InFieldNumberOrder()) { // Enum type will later be used to call this contract resolver. // Register the enum type so we know to resolve its names from the descriptor. if (field.FieldType == FieldType.Enum) { _enumTypeMapping.TryAdd(field.EnumType.ClrType, field.EnumType); } Type fieldType; if (field.IsMap) { var mapFields = field.MessageType.Fields.InFieldNumberOrder(); var valueType = MessageDescriptorHelpers.ResolveFieldType(mapFields[1]); fieldType = typeof(IDictionary <,>).MakeGenericType(typeof(string), valueType); } else if (field.IsRepeated) { fieldType = typeof(IList <>).MakeGenericType(MessageDescriptorHelpers.ResolveFieldType(field)); } else { fieldType = MessageDescriptorHelpers.ResolveFieldType(field); } properties.Add(new DataProperty(field.JsonName, fieldType)); } var schema = DataContract.ForObject(messageDescriptor.ClrType, properties: properties); // var schema = new DataContract(DataType.Object, messageDescriptor.ClrType, properties: properties); return(schema); }