private static List <EntitySet> CreateEntitySets(SchemaGenerationContext context) { var entitySets = new List <EntitySet>(); foreach (var entityType in context.EntityTypes) { entitySets.Add(new EntitySet { Name = entityType.Name, EntityType = string.Concat(schemaNamespace, ".", entityType.Name), }); } return(entitySets); }
/// <inheritdoc /> public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (_validatorFactory == null) { _logger.LogWarning(0, "ValidatorFactory is not provided. Please register FluentValidation."); return; } if (schema == null) { return; } IValidator?validator = null; try { validator = _validatorFactory.GetValidator(context.Type); } catch (Exception e) { _logger.LogWarning(0, e, $"GetValidator for type '{context.Type}' fails."); } if (validator == null) { return; } var schemaProvider = new SwashbuckleSchemaProvider(context.SchemaRepository, context.SchemaGenerator, _schemaGenerationSettings.SchemaIdSelector); var schemaContext = new SchemaGenerationContext( schema: schema, schemaType: context.Type, rules: _rules, schemaGenerationOptions: _schemaGenerationOptions, schemaGenerationSettings: _schemaGenerationSettings, schemaProvider: schemaProvider); ApplyRulesToSchema(context, validator, schemaContext); try { AddRulesFromIncludedValidators(context, validator, schemaContext); } catch (Exception e) { _logger.LogWarning(0, e, $"Applying IncludeRules for type '{context.Type}' fails."); } }
private static void CreateEntityType(Content content, SchemaGenerationContext context, bool isCollection) { var list = content.ContentHandler as ContentList; if (list == null) { list = (ContentList)content.ContentHandler.LoadContentList(); } context.ListFieldSettings = list == null ? EmtpyFieldSettings : list.FieldSettings; if (isCollection) { IEnumerable <ContentType> contentTypes = null; var gc = content.ContentHandler as GenericContent; if (gc != null) { contentTypes = gc.GetAllowedChildTypes(); } if (contentTypes == null || contentTypes.Count() == 0) { context.Flattening = true; contentTypes = ContentType.GetContentTypes(); } else { context.Flattening = false; } CreateEntityTypes(contentTypes, context); } else { var contentType = content.ContentType; context.Flattening = true; var entityType = new EntityType { Name = contentType.Name, BaseType = contentType.ParentTypeName, Key = GetKey(contentType, context), Properties = new List <Property>(), NavigationProperties = new List <NavigationProperty>() }; context.EntityTypes.Add(entityType); CreatePropertiesFromFieldSettings(content.ContentType.FieldSettings, contentType, entityType, context); } }
private static void CreateEntityType(ContentType contentType, SchemaGenerationContext context) { var entityType = new EntityType { Name = contentType.Name, BaseType = contentType.ParentTypeName, Key = GetKey(contentType, context), Properties = new List <Property>(), NavigationProperties = new List <NavigationProperty>() }; context.EntityTypes.Add(entityType); CreatePropertiesFromFieldSettings(contentType.FieldSettings, contentType, entityType, context); }
private static void CreateComplexType(Type type, SchemaGenerationContext context) { var typeName = type.FullName.Replace("+", "."); if (typeName.StartsWith("System.")) { return; } if (context.ComplexTypes.Any(x => x.Name == typeName)) { return; } if (IsContentHandler(type)) { return; } var complexType = new ComplexType { Name = typeName, Properties = new List <Property>() }; context.ComplexTypes.Add(complexType); foreach (var propInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var attrs = propInfo.GetCustomAttributes(true).Select(x => x.GetType()); if (_prohibitiveAttributes.Except(attrs).Count() != _prohibitiveAttributes.Length) { continue; } var property = CreateProperty(propInfo.Name, propInfo.PropertyType, context); if (property != null) { complexType.Properties.Add(property); } } foreach (var fieldInfo in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) { var property = CreateProperty(fieldInfo.Name, fieldInfo.FieldType, context); if (property != null) { complexType.Properties.Add(property); } } }
private static List <AssociationSet> CreateAssociationSets(SchemaGenerationContext context) { var associationSets = new List <AssociationSet>(); foreach (var association in context.Associations) { associationSets.Add(new AssociationSet { Name = association.Name, Association = string.Concat(schemaNamespace, ".", association.Name), End1 = new AssociationSetEnd { Role = association.End1.Role, EntitySet = association.End1.Type }, End2 = new AssociationSetEnd { Role = association.End2.Role, EntitySet = association.End2.Type } }); } return(associationSets); }
private static Edmx CreateEdmx(Content content, bool isCollection) { var context = new SchemaGenerationContext(); CreateEntityType(content, context, isCollection); return(new Edmx { DataServices = new DataServices { DataServiceVersion = MetaGenerator.dataServiceVersion, Schemas = new[] { new Metadata.Schema { EntityTypes = context.EntityTypes, ComplexTypes = context.ComplexTypes, EnumTypes = context.EnumTypes, Associations = context.Associations, EntityContainer = CreateEntityContainer(context) } } } }); }
private static Property CreateProperty(string name, Type type, SchemaGenerationContext context) { var attributes = new List <KeyValue>(); if (name == "Name") { attributes.Add(new KeyValue { Key = "m:FC_TargetPath", Value = "SyndicationTitle" }); attributes.Add(new KeyValue { Key = "m:FC_ContentKind", Value = "text" }); attributes.Add(new KeyValue { Key = "m:FC_KeepInContent", Value = "false" }); } if (name == "Description") { attributes.Add(new KeyValue { Key = "m:FC_TargetPath", Value = "SyndicationSummary" }); attributes.Add(new KeyValue { Key = "m:FC_ContentKind", Value = "text" }); attributes.Add(new KeyValue { Key = "m:FC_KeepInContent", Value = "false" }); } var nullable = true; var property = new Property { Name = name, Type = GetPropertyType(type, context), Nullable = nullable, Attributes = attributes.Count > 0 ? attributes : null, }; return(property); }
private static void CreatePropertyFromFieldSetting(FieldSetting fieldSetting, ContentType contentType, EntityType entityType, SchemaGenerationContext context) { if (!context.Flattening && fieldSetting.Owner != contentType && fieldSetting.Owner != ContentListContentType) { return; } if (ODataHandler.DisabledFieldNames.Contains(fieldSetting.Name)) { return; } var refField = fieldSetting as ReferenceFieldSetting; if (refField != null) { entityType.NavigationProperties.Add(CreateNavigationProperty(refField, context)); return; } entityType.Properties.Add(CreateProperty(fieldSetting, context)); }
private static void CreatePropertiesFromFieldSettings(IEnumerable <FieldSetting> fieldSettings, ContentType contentType, EntityType entityType, SchemaGenerationContext context) { var properties = entityType.Properties; var navigationProperties = entityType.NavigationProperties; foreach (var fieldSetting in fieldSettings) { CreatePropertyFromFieldSetting(fieldSetting, contentType, entityType, context); } foreach (var fieldSetting in context.ListFieldSettings) { CreatePropertyFromFieldSetting(fieldSetting, contentType, entityType, context); } }
private void AddRulesFromIncludedValidators(SchemaFilterContext context, IValidator validator, SchemaGenerationContext schemaGenerationContext) { FluentValidationSchemaBuilder.AddRulesFromIncludedValidators( validator: validator, logger: _logger, schemaGenerationContext: schemaGenerationContext); }
/// <summary> /// Applies rules from validator. /// </summary> internal static void ApplyRulesToSchema( Type schemaType, IEnumerable <string>?schemaPropertyNames, IValidator validator, ILogger logger, SchemaGenerationContext schemaGenerationContext) { OpenApiSchema schema = schemaGenerationContext.Schema; var schemaTypeName = schemaType.Name; var lazyLog = new LazyLog(logger, l => l.LogDebug($"Applying FluentValidation rules to swagger schema '{schemaTypeName}'.")); var validationRules = validator .GetValidationRules() .Where(context => context.ReflectionContext != null) .ToArray(); schemaPropertyNames ??= schema.Properties?.Keys ?? Array.Empty <string>(); foreach (var schemaPropertyName in schemaPropertyNames) { ValidationRuleInfo?validationRuleInfo = validationRules .FirstOrDefault(propertyRule => IsMatchesRule(propertyRule, schemaPropertyName, schemaGenerationContext.SchemaGenerationSettings)); if (validationRuleInfo != null) { var propertyValidators = validationRuleInfo.PropertyRule.GetValidators(); foreach (var propertyValidator in propertyValidators) { foreach (var rule in schemaGenerationContext.Rules) { if (rule.IsMatches(propertyValidator)) { try { var ruleHistoryItem = new RuleHistoryCache.RuleHistoryItem(schemaTypeName, schemaPropertyName, propertyValidator, rule.Name); if (!schema.ContainsRuleHistoryItem(ruleHistoryItem)) { lazyLog.LogOnce(); var ruleContext = new RuleContext( schema: schema, propertyKey: schemaPropertyName, validationRuleInfo: validationRuleInfo, propertyValidator: propertyValidator, reflectionContext: validationRuleInfo.ReflectionContext); rule.Apply(ruleContext); logger.LogDebug($"Rule '{rule.Name}' applied for property '{schemaTypeName}.{schemaPropertyName}'."); schema.AddRuleHistoryItem(ruleHistoryItem); } else { logger.LogDebug($"Rule '{rule.Name}' already applied for property '{schemaTypeName}.{schemaPropertyName}'."); } } catch (Exception e) { logger.LogWarning(0, e, $"Error on apply rule '{rule.Name}' for property '{schemaTypeName}.{schemaPropertyName}'."); } } } } } } }
internal static void AddRulesFromIncludedValidators( IValidator validator, ILogger logger, SchemaGenerationContext schemaGenerationContext) { // Note: IValidatorDescriptor doesn't return IncludeRules so we need to get validators manually. var validationRules = validator .GetValidationRules() .ToArrayDebug(); var propertiesWithChildAdapters = validationRules .Select(context => (context.PropertyRule, context.PropertyRule.GetValidators().OfType <IChildValidatorAdaptor>().ToArray())) .ToArrayDebug(); foreach ((IValidationRule propertyRule, IChildValidatorAdaptor[] childAdapters) in propertiesWithChildAdapters) { foreach (var childAdapter in childAdapters) { IValidator?childValidator = childAdapter.GetValidatorFromChildValidatorAdapter(); if (childValidator != null) { var canValidateInstancesOfType = childValidator.CanValidateInstancesOfType(schemaGenerationContext.SchemaType); if (canValidateInstancesOfType) { // It's a validator for current type (Include for example) so apply changes to current schema. ApplyRulesToSchema( schemaType: schemaGenerationContext.SchemaType, schemaPropertyNames: null, validator: childValidator, logger: logger, schemaGenerationContext: schemaGenerationContext); AddRulesFromIncludedValidators( validator: childValidator, logger: logger, schemaGenerationContext: schemaGenerationContext); } else { // It's a validator for sub schema so get schema and apply changes to it. var schemaForChildValidator = schemaGenerationContext.SchemaProvider.GetSchemaForType(propertyRule.TypeToValidate); var childSchemaContext = schemaGenerationContext with { Schema = schemaForChildValidator }; ApplyRulesToSchema( schemaType: propertyRule.TypeToValidate, schemaPropertyNames: null, validator: childValidator, logger: logger, schemaGenerationContext: childSchemaContext); AddRulesFromIncludedValidators( validator: childValidator, logger: logger, schemaGenerationContext: childSchemaContext); } } } } }
private void ApplyInternal(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) { return; } if (_validatorFactory == null) { _logger.LogWarning(0, "ValidatorFactory is not provided. Please register FluentValidation."); return; } var schemaProvider = new SwashbuckleSchemaProvider(context.SchemaRepository, context.SchemaGenerator, _schemaGenerationSettings.SchemaIdSelector); foreach (var operationParameter in operation.Parameters) { var apiParameterDescription = context.ApiDescription.ParameterDescriptions.FirstOrDefault(description => description.Name.Equals(operationParameter.Name, StringComparison.InvariantCultureIgnoreCase)); var modelMetadata = apiParameterDescription?.ModelMetadata; if (modelMetadata != null) { var parameterType = modelMetadata.ContainerType; if (parameterType == null) { continue; } var validator = _validatorFactory.GetValidator(parameterType); if (validator == null) { continue; } OpenApiSchema schema = schemaProvider.GetSchemaForType(parameterType); if (schema.Properties != null && schema.Properties.Count > 0) { var schemaPropertyName = operationParameter.Name; KeyValuePair <string, OpenApiSchema> apiProperty = schema.Properties.FirstOrDefault(property => property.Key.EqualsIgnoreAll(schemaPropertyName)); if (apiProperty.Key != null) { schemaPropertyName = apiProperty.Key; } else { var propertyInfo = parameterType.GetProperty(schemaPropertyName); if (propertyInfo != null && _schemaGenerationSettings.NameResolver != null) { schemaPropertyName = _schemaGenerationSettings.NameResolver?.GetPropertyName(propertyInfo); } } var schemaContext = new SchemaGenerationContext( schema: schema, schemaType: parameterType, rules: _rules, schemaGenerationOptions: _schemaGenerationOptions, schemaGenerationSettings: _schemaGenerationSettings, schemaProvider: schemaProvider); FluentValidationSchemaBuilder.ApplyRulesToSchema( schemaType: parameterType, schemaPropertyNames: new[] { schemaPropertyName }, validator: validator, logger: _logger, schemaGenerationContext: schemaContext); if (schema.Required != null) { operationParameter.Required = schema.Required.Contains(schemaPropertyName, IgnoreAllStringComparer.Instance); } var parameterSchema = operationParameter.Schema; if (parameterSchema != null) { if (schema.Properties.TryGetValue(schemaPropertyName.ToLowerCamelCase(), out var property) || schema.Properties.TryGetValue(schemaPropertyName, out property)) { // Copy from property schema to parameter schema. parameterSchema.MinLength = property.MinLength; parameterSchema.Nullable = property.Nullable; parameterSchema.MaxLength = property.MaxLength; parameterSchema.Pattern = property.Pattern; parameterSchema.Minimum = property.Minimum; parameterSchema.Maximum = property.Maximum; parameterSchema.ExclusiveMaximum = property.ExclusiveMaximum; parameterSchema.ExclusiveMinimum = property.ExclusiveMinimum; parameterSchema.AllOf = property.AllOf; } } } } } }
private static NavigationProperty CreateNavigationProperty(ReferenceFieldSetting refField, SchemaGenerationContext context) { var associationName = String.Concat(refField.Owner.Name, "_", refField.Name); var fromName = String.Concat(associationName, "_From"); var toName = String.Concat(associationName, "_To"); if (!context.Associations.Any(x => x.Name == associationName)) { var ancestorName = GetNearestAncestorName(refField.AllowedTypes); context.Associations.Add(new Association { Name = associationName, End1 = new AssociationEnd { Type = refField.Owner.Name, Role = fromName, Multiplicity = "1" }, End2 = new AssociationEnd { Type = ancestorName, Role = toName, Multiplicity = refField.AllowMultiple == true ? "*" : refField.Compulsory == true ? "1" : "0..1" } }); } return(new NavigationProperty { Name = refField.Name, ToRole = toName, FromRole = fromName, Relationship = associationName }); }
private static Property CreateProperty(FieldSetting fieldSetting, SchemaGenerationContext context) { Property property; var attributes = new List <KeyValue>(); if (fieldSetting.Name == "Name") { attributes.Add(new KeyValue { Key = "m:FC_TargetPath", Value = "SyndicationTitle" }); attributes.Add(new KeyValue { Key = "m:FC_ContentKind", Value = "text" }); attributes.Add(new KeyValue { Key = "m:FC_KeepInContent", Value = "false" }); } if (fieldSetting.Name == "Description") { attributes.Add(new KeyValue { Key = "m:FC_TargetPath", Value = "SyndicationSummary" }); attributes.Add(new KeyValue { Key = "m:FC_ContentKind", Value = "text" }); attributes.Add(new KeyValue { Key = "m:FC_KeepInContent", Value = "false" }); } var choiceFieldSetting = fieldSetting as ChoiceFieldSetting; if (choiceFieldSetting != null) { var choiceTypeName = String.Concat(choiceFieldSetting.Owner.Name, ".", fieldSetting.Name); if (!context.EnumTypes.Any(x => x.Name == choiceTypeName)) { EnumType enumType; if (choiceFieldSetting.FieldDataType.IsEnum) { enumType = new EnumType { Name = choiceTypeName, UnderlyingEnumType = choiceFieldSetting.FieldDataType } } ; else { enumType = new EnumType { Name = choiceTypeName, UnderlyingFieldSetting = choiceFieldSetting } }; context.EnumTypes.Add(enumType); } property = new Property { Name = fieldSetting.Name, FieldType = fieldSetting.ShortName, Type = choiceTypeName, Nullable = !fieldSetting.Compulsory.HasValue || !fieldSetting.Compulsory.Value, DefaultValue = fieldSetting.DefaultValue, Attributes = attributes.Count > 0 ? attributes : null, }; return(property); } property = new Property { Name = fieldSetting.Name, Type = GetPropertyType(fieldSetting, context), FieldType = fieldSetting.ShortName, Nullable = !fieldSetting.Compulsory.HasValue || !fieldSetting.Compulsory.Value, DefaultValue = fieldSetting.DefaultValue, Attributes = attributes.Count > 0 ? attributes : null, }; var textFieldSetting = fieldSetting as TextFieldSetting; if (textFieldSetting != null) { property.MaxLength = textFieldSetting.MaxLength; } return(property); }
private static void CreateEntityTypes(SchemaGenerationContext context) { context.WithChildren = true; context.ListFieldSettings = EmtpyFieldSettings; CreateEntityTypes(ContentType.GetRootTypes(), context); }
private static List <FunctionImport> CreateFunctionImports(SchemaGenerationContext context) { return(new List <FunctionImport>()); }
private static void CreateEntityTypes(IEnumerable <ContentType> contentTypes, SchemaGenerationContext context) { context.Flattening = true; foreach (var contentType in contentTypes) { CreateEntityType(contentType, context); } }
private static string GetPropertyType(Type t, SchemaGenerationContext context) { if (t == null) { return("null"); } var type = GetPrimitivePropertyType(t); if (type != null) { return(type); } if (t.IsEnum) { if (!context.EnumTypes.Any(x => x.Name == t.FullName)) { var enumType = new EnumType { Name = t.FullName, UnderlyingEnumType = t }; context.EnumTypes.Add(enumType); } return(t.FullName); } if (t.IsInterface) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { type = String.Concat("Collection(", GetPropertyType(t.GetGenericArguments()[0], context), ")"); } else if (typeof(IEnumerable).IsAssignableFrom(t)) { type = String.Concat("Collection(", typeof(object).Name, ")"); } else { CreateComplexType(t, context); type = t.FullName; } } else { var iface = t.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable <>)); if (iface != null) { type = String.Concat("Collection(", GetPropertyType(iface.GetGenericArguments()[0], context), ")"); } else if (typeof(IEnumerable).IsAssignableFrom(t)) { type = String.Concat("Collection(", typeof(object).Name, ")"); } else { CreateComplexType(t, context); type = t.FullName.Replace("+", "."); } } return(type); }
private static void CreateEntityTypes(SchemaGenerationContext context) { context.ListFieldSettings = EmtpyFieldSettings; CreateEntityTypes(ContentType.GetContentTypes(), context); }
private static void CreateEntityTypes(IEnumerable <ContentType> contentTypes, SchemaGenerationContext context) { foreach (var contentType in contentTypes) { if (context.IsPermitteType(contentType)) { CreateEntityType(contentType, context); } } }
private void ApplyRulesToSchema(SchemaFilterContext context, IValidator validator, SchemaGenerationContext schemaGenerationContext) { FluentValidationSchemaBuilder.ApplyRulesToSchema( schemaType: context.Type, schemaPropertyNames: null, validator: validator, logger: _logger, schemaGenerationContext: schemaGenerationContext); }