private TypeSchemaKey CreateKey(Required valueRequired, JsonProperty memberProperty, JsonContract contract) { int? minLength = AttributeHelpers.GetMinLength(memberProperty); int? maxLength = AttributeHelpers.GetMaxLength(memberProperty); string title = GetTitle(contract.NonNullableUnderlyingType, memberProperty); string description = GetDescription(contract.NonNullableUnderlyingType, memberProperty); Required resolvedRequired; switch (valueRequired) { case Required.Default: case Required.AllowNull: resolvedRequired = Required.AllowNull; break; case Required.Always: case Required.DisallowNull: resolvedRequired = Required.DisallowNull; break; default: throw new ArgumentOutOfRangeException(nameof(valueRequired)); } TypeSchemaKey key = new TypeSchemaKey(contract.UnderlyingType, resolvedRequired, minLength, maxLength, title, description); return(key); }
private void PopulatePrimativeSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { Type nonNullableUnderlyingType = GetNonNullableUnderlyingType(contract); JSchemaType type = GetJSchemaType(contract.UnderlyingType, valueRequired); if (type != Constants.AnyType) { schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired); } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) { if (AttributeHelpers.GetStringLength(memberProperty, out int minimumLength, out int maximumLength)) { schema.MinimumLength = minimumLength; schema.MaximumLength = maximumLength; } else { schema.MinimumLength = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumLength = AttributeHelpers.GetMaxLength(memberProperty); } schema.Pattern = AttributeHelpers.GetPattern(memberProperty); schema.Format = AttributeHelpers.GetFormat(memberProperty); // no format specified, derive from type if (schema.Format == null) { if (nonNullableUnderlyingType == typeof(DateTime) || nonNullableUnderlyingType == typeof(DateTimeOffset)) { schema.Format = Constants.Formats.DateTime; } else if (nonNullableUnderlyingType == typeof(Uri)) { schema.Format = Constants.Formats.Uri; } } }
private void PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { schema.Title = GetTitle(contract.NonNullableUnderlyingType, memberProperty); schema.Description = GetDescription(contract.NonNullableUnderlyingType, memberProperty); JsonConverter converter; if (contract.Converter != null && contract.Converter.CanWrite) { converter = contract.Converter; } else if (contract.InternalConverter != null && contract.InternalConverter.CanWrite) { converter = contract.InternalConverter; } else { converter = null; } if (converter != null) { schema.Type = null; } else { switch (contract.ContractType) { case JsonContractType.Object: if (contract.NonNullableUnderlyingType == typeof(object)) { PopulatePrimativeSchema(schema, contract, memberProperty, valueRequired); } else { if (schema.Id == null) { schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Object, valueRequired); GenerateObjectSchema(schema, contract.NonNullableUnderlyingType, (JsonObjectContract)contract); } break; case JsonContractType.Array: if (schema.Id == null) { schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Array, valueRequired); schema.MinimumItems = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumItems = AttributeHelpers.GetMaxLength(memberProperty); JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(contract.NonNullableUnderlyingType); Required?required = null; if (arrayAttribute != null && !arrayAttribute.AllowNullItems) { required = Required.Always; } Type collectionItemType = ReflectionUtils.GetCollectionItemType(contract.NonNullableUnderlyingType); if (collectionItemType != null) { schema.Items.Add(GenerateInternal(collectionItemType, required, null, (JsonArrayContract)contract, null)); } break; case JsonContractType.Primitive: PopulatePrimativeSchema(schema, contract, memberProperty, valueRequired); break; case JsonContractType.String: JSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType)) ? JSchemaType.String : AddNullType(JSchemaType.String, valueRequired); schema.Type = schemaType; schema.MinimumLength = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumLength = AttributeHelpers.GetMaxLength(memberProperty); break; case JsonContractType.Dictionary: schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.MinimumProperties = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumProperties = AttributeHelpers.GetMaxLength(memberProperty); ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out Type keyType, out Type valueType); if (keyType != null) { JsonContract keyContract = _generator.ContractResolver.ResolveContract(keyType); // can be converted to a string if (keyContract.ContractType == JsonContractType.Primitive) { schema.AdditionalProperties = GenerateInternal(valueType, _generator.DefaultRequired, null, (JsonDictionaryContract)contract, null); } } break; case JsonContractType.Serializable: if (schema.Id == null) { schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.AllowAdditionalProperties = true; break; case JsonContractType.Dynamic: case JsonContractType.Linq: schema.Type = null; break; default: throw new JSchemaException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); } } }
private void PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { Type nonNullableUnderlyingType = GetNonNullableUnderlyingType(contract); schema.Title = GetTitle(nonNullableUnderlyingType, memberProperty); schema.Description = GetDescription(nonNullableUnderlyingType, memberProperty); JsonConverter converter; if (contract.Converter != null && contract.Converter.CanWrite) { converter = contract.Converter; } else if (contract.InternalConverter != null && contract.InternalConverter.CanWrite) { converter = contract.InternalConverter; } else { converter = null; } if (converter != null) { schema.Type = null; } else { switch (contract) { case JsonObjectContract objectContract: if (nonNullableUnderlyingType == typeof(object)) { PopulatePrimativeSchema(schema, objectContract, memberProperty, valueRequired); } else { if (schema.Id == null) { schema.Id = GetTypeId(nonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Object, valueRequired); GenerateObjectSchema(schema, nonNullableUnderlyingType, objectContract); } break; case JsonArrayContract arrayContract: if (schema.Id == null) { schema.Id = GetTypeId(nonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Array, valueRequired); schema.MinimumItems = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumItems = AttributeHelpers.GetMaxLength(memberProperty); schema.UniqueItems = ReflectionUtils.IsISetType(nonNullableUnderlyingType) || AttributeHelpers.GetUniqueItems(memberProperty); JsonArrayAttribute arrayAttribute = ReflectionUtils.GetAttribute <JsonArrayAttribute>(nonNullableUnderlyingType); Required?required = null; if (arrayAttribute != null && !arrayAttribute.AllowNullItems) { required = Required.Always; } Type collectionItemType = ReflectionUtils.GetCollectionItemType(nonNullableUnderlyingType); if (collectionItemType != null) { schema.Items.Add(GenerateInternal(collectionItemType, required, null, arrayContract, null)); } break; case JsonStringContract stringContract: JSchemaType schemaType = (!ReflectionUtils.IsNullable(stringContract.UnderlyingType)) ? JSchemaType.String : AddNullType(JSchemaType.String, valueRequired); schema.Type = schemaType; schema.MinimumLength = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumLength = AttributeHelpers.GetMaxLength(memberProperty); break; case JsonPrimitiveContract primitiveContract: PopulatePrimativeSchema(schema, primitiveContract, memberProperty, valueRequired); break; case JsonDictionaryContract dictionaryContract: schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.MinimumProperties = AttributeHelpers.GetMinLength(memberProperty); schema.MaximumProperties = AttributeHelpers.GetMaxLength(memberProperty); ReflectionUtils.GetDictionaryKeyValueTypes(nonNullableUnderlyingType, out Type keyType, out Type valueType); if (keyType != null) { JsonContract keyContract = _generator.ContractResolver.ResolveContract(keyType); // can be converted to a string if (keyContract is JsonPrimitiveContract) { schema.AdditionalProperties = GenerateInternal(valueType, _generator.DefaultRequired, null, dictionaryContract, null); } } break; #if !PORTABLE || NETSTANDARD1_3 || NETSTANDARD2_0 case JsonISerializableContract serializableContract: if (schema.Id == null) { schema.Id = GetTypeId(nonNullableUnderlyingType, false); } schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.AllowAdditionalProperties = true; break; #endif #if !NET35 case JsonDynamicContract dynamicContract: #endif case JsonLinqContract linqContract: schema.Type = null; break; default: throw new JSchemaException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); } } }