private static TypeSchemaKey CreateKey(Required valueRequired, JsonProperty memberProperty, JsonContract contract) { int?minLength = DataAnnotationHelpers.GetMinLength(memberProperty); int?maxLength = DataAnnotationHelpers.GetMaxLength(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); return(key); }
private static TypeSchemaKey CreateKey(Required valueRequired, JsonProperty memberProperty, JsonContract contract) { int?minLength = DataAnnotationHelpers.GetMinLength(memberProperty); int?maxLength = DataAnnotationHelpers.GetMaxLength(memberProperty); TypeSchemaKey key = new TypeSchemaKey(contract.UnderlyingType, valueRequired, minLength, maxLength); return(key); }
private void PopulatePrimativeSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { JSchemaType type = GetJSchemaType(contract.UnderlyingType, valueRequired); if (type != Constants.AnyType) { schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired); } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) { if (DataAnnotationHelpers.GetStringLength(memberProperty, out int minimumLength, out int maximumLength)) { schema.MinimumLength = minimumLength; schema.MaximumLength = maximumLength; } else { schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); } schema.Pattern = DataAnnotationHelpers.GetPattern(memberProperty); schema.Format = DataAnnotationHelpers.GetFormat(memberProperty); // no format specified, derive from type if (schema.Format == null) { if (contract.NonNullableUnderlyingType == typeof(DateTime) || contract.NonNullableUnderlyingType == typeof(DateTimeOffset)) { schema.Format = Constants.Formats.DateTime; } else if (contract.NonNullableUnderlyingType == typeof(Uri)) { schema.Format = Constants.Formats.Uri; } } }
private void PopulatePrimativeSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { JSchemaType type = GetJSchemaType(contract.UnderlyingType, valueRequired); if (type != Constants.AnyType) { schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired); } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) { int minimumLength; int maximumLength; if (DataAnnotationHelpers.GetStringLength(memberProperty, out minimumLength, out maximumLength)) { schema.MinimumLength = minimumLength; schema.MaximumLength = maximumLength; } else { schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); } schema.Pattern = DataAnnotationHelpers.GetPattern(memberProperty); schema.Format = DataAnnotationHelpers.GetFormat(memberProperty); } if (JSchemaTypeHelpers.HasFlag(type, JSchemaType.Number) || JSchemaTypeHelpers.HasFlag(type, JSchemaType.Integer)) { double minimum; double maximum; if (DataAnnotationHelpers.GetRange(memberProperty, out minimum, out maximum)) { schema.Minimum = minimum; schema.Maximum = maximum; } } if (JSchemaTypeHelpers.HasFlag(type, JSchemaType.Integer) && contract.NonNullableUnderlyingType.IsEnum() && ReflectionUtils.GetAttribute <FlagsAttribute>(contract.NonNullableUnderlyingType) == null) { if ((type & JSchemaType.Null) == JSchemaType.Null) { schema.Enum.Add(JValue.CreateNull()); } IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(contract.NonNullableUnderlyingType); foreach (EnumValue <long> enumValue in enumValues) { JToken value = JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } Type enumDataType = DataAnnotationHelpers.GetEnumDataType(memberProperty); if (enumDataType != null && CollectionUtils.IsNullOrEmpty(schema._enum)) { IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(enumDataType); foreach (EnumValue <long> enumValue in enumValues) { JToken value = (JSchemaTypeHelpers.HasFlag(type, JSchemaType.String)) ? enumValue.Name : JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } }
private void PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { schema.Title = GetTitle(contract.NonNullableUnderlyingType); schema.Description = GetDescription(contract.NonNullableUnderlyingType); 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 = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumItems = DataAnnotationHelpers.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 = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); break; case JsonContractType.Dictionary: schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.MinimumProperties = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumProperties = DataAnnotationHelpers.GetMaxLength(memberProperty); Type keyType; Type valueType; ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out keyType, out 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 JSchema PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { schema.Title = GetTitle(contract.NonNullableUnderlyingType); schema.Description = GetDescription(contract.NonNullableUnderlyingType); JsonConverter converter = contract.Converter ?? contract.InternalConverter; if (converter != null) { // todo: Add GetSchema to JsonConverter and use here? schema.Type = JSchemaType.Any; } else { switch (contract.ContractType) { case JsonContractType.Object: 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 = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumItems = DataAnnotationHelpers.GetMaxLength(memberProperty); JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute <JsonArrayAttribute>(contract.NonNullableUnderlyingType); bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems); Type collectionItemType = ReflectionUtils.GetCollectionItemType(contract.NonNullableUnderlyingType); if (collectionItemType != null) { schema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, null, (JsonArrayContract)contract)); } break; case JsonContractType.Primitive: schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired); if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) { int minimumLength; int maximumLength; if (DataAnnotationHelpers.GetStringLength(memberProperty, out minimumLength, out maximumLength)) { schema.MinimumLength = minimumLength; schema.MaximumLength = maximumLength; } else { schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); } schema.Pattern = DataAnnotationHelpers.GetPattern(memberProperty); schema.Format = DataAnnotationHelpers.GetFormat(memberProperty); } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Float) || JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer)) { double minimum; double maximum; if (DataAnnotationHelpers.GetRange(memberProperty, out minimum, out maximum)) { schema.Minimum = minimum; schema.Maximum = maximum; } } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer) && contract.NonNullableUnderlyingType.IsEnum() && ReflectionUtils.GetAttribute <FlagsAttribute>(contract.NonNullableUnderlyingType) == null) { IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(contract.NonNullableUnderlyingType); foreach (EnumValue <long> enumValue in enumValues) { JToken value = JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } Type enumDataType = DataAnnotationHelpers.GetEnumDataType(memberProperty); if (enumDataType != null && CollectionUtils.IsNullOrEmpty(schema._enum)) { IList <EnumValue <long> > enumValues = EnumUtils.GetNamesAndValues <long>(enumDataType); foreach (EnumValue <long> enumValue in enumValues) { JToken value = (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) ? enumValue.Name : JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } break; case JsonContractType.String: JSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType)) ? JSchemaType.String : AddNullType(JSchemaType.String, valueRequired); schema.Type = schemaType; schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); break; case JsonContractType.Dictionary: schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.MinimumProperties = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumProperties = DataAnnotationHelpers.GetMaxLength(memberProperty); Type keyType; Type valueType; ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out keyType, out valueType); if (keyType != null) { JsonContract keyContract = ContractResolver.ResolveContract(keyType); // can be converted to a string if (keyContract.ContractType == JsonContractType.Primitive) { schema.AdditionalProperties = GenerateInternal(valueType, Required.Default, null, (JsonDictionaryContract)contract); } } 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 = JSchemaType.Any; break; default: throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); } } return(schema); }