public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema == null) { throw new ArgumentNullException(nameof(schema)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } if (schema.Properties.Count == 0) { return; } var excludeAttributes = context.Type.GetCustomAttributes <ModelExcludeFilterAttribute>(true) .SelectMany(a => a.ExcludeAttributes).ToList(); if (!excludeAttributes.Any()) { return; } foreach (var prop in excludeAttributes) { var schemaProp = schema.Properties.Where(p => string.Equals(p.Key, prop, StringComparison.OrdinalIgnoreCase)).Select(p => p.Key) .SingleOrDefault(); if (schemaProp != null) { schema.Properties.Remove(schemaProp); } } }
/// <summary> /// Applies the specified model. /// </summary> /// <param name="model">The model.</param> /// <param name="context">The context.</param> public void Apply(Schema model, SchemaFilterContext context) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.SystemType == typeof(ModelStateDictionary)) { var modelState = new ModelStateDictionary(); modelState.AddModelError("Property1", "Error message 1"); modelState.AddModelError("Property1", "Error message 2"); modelState.AddModelError("Property2", "Error message 3"); var serializableError = new SerializableError(modelState); model.Default = serializableError; model.Example = serializableError; } }
public void Apply(Schema schema, SchemaFilterContext context) { var jsonObjectContract = context.JsonContract as JsonObjectContract; if (jsonObjectContract == null) { return; } var commentId = XmlCommentsIdHelper.GetCommentIdForType(context.SystemType); var typeNode = _xmlNavigator.SelectSingleNode(string.Format(MemberXPath, commentId)); if (typeNode != null) { var summaryNode = typeNode.SelectSingleNode(SummaryTag); if (summaryNode != null) { schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); } } foreach (var entry in schema.Properties) { var jsonProperty = jsonObjectContract.Properties[entry.Key]; if (jsonProperty == null) { continue; } var propertyInfo = jsonProperty.PropertyInfo(); if (propertyInfo != null) { ApplyPropertyComments(entry.Value, propertyInfo); } } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var type = context.Type; schema.Example = GetExampleOrNullFor(type); }
public void Apply(Schema schema, SchemaFilterContext context) { // schema.Properties?.Remove("bookId"); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Example = SchemaFiltersMock.GetErrorResponse("Forbidden"); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema == null) { throw new ArgumentNullException(nameof(schema)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } if ((context.Type == null) || !context.Type.IsEnum) { return; } if (context.Type.IsDefined(typeof(FlagsAttribute), false)) { schema.Format = "flags"; } OpenApiObject definition = new(); foreach (object?enumValue in context.Type.GetEnumValues()) { if (enumValue == null) { continue; } string?enumName = Enum.GetName(context.Type, enumValue); if (string.IsNullOrEmpty(enumName)) { enumName = enumValue.ToString(); if (string.IsNullOrEmpty(enumName)) { continue; } } IOpenApiAny enumObject; if (TryCast(enumValue, out int intValue)) { enumObject = new OpenApiInteger(intValue); } else if (TryCast(enumValue, out long longValue)) { enumObject = new OpenApiLong(longValue); } else if (TryCast(enumValue, out ulong ulongValue)) { // OpenApi spec doesn't support ulongs as of now enumObject = new OpenApiString(ulongValue.ToString(CultureInfo.InvariantCulture)); } else { throw new InvalidOperationException(nameof(enumValue)); } definition.Add(enumName !, enumObject); } schema.AddExtension("x-definition", definition); }
internal static void AddRulesFromIncludedValidators( OpenApiSchema schema, SchemaFilterContext schemaFilterContext, IValidator validator, IReadOnlyCollection <FluentValidationRule> rules, ILogger logger) { // Note: IValidatorDescriptor doesn't return IncludeRules so we need to get validators manually. var validationRules = (validator as IEnumerable <IValidationRule>) .NotNull() .OfType <PropertyRule>() .Where(includeRule => includeRule.HasNoCondition()) .ToArray(); var propertiesWithChildAdapters = validationRules .Select(rule => (rule, rule.Validators.OfType <IChildValidatorAdaptor>().ToArray())) .ToArrayDebug(); foreach ((PropertyRule propertyRule, IChildValidatorAdaptor[] childAdapters) in propertiesWithChildAdapters) { foreach (var childAdapter in childAdapters) { IValidator?childValidator = childAdapter.GetValidatorFromChildValidatorAdapter(); if (childValidator != null) { var canValidateInstancesOfType = childValidator.CanValidateInstancesOfType(schemaFilterContext.Type); if (canValidateInstancesOfType) { // It's a validator for current type (Include for example) so apply changes to current schema. ApplyRulesToSchema( schema: schema, schemaType: schemaFilterContext.Type, schemaPropertyNames: null, schemaFilterContext: schemaFilterContext, validator: childValidator, rules: rules, logger: logger); AddRulesFromIncludedValidators( schema: schema, schemaFilterContext: schemaFilterContext, validator: childValidator, rules: rules, logger: logger); } else { // It's a validator for sub schema so get schema and apply changes to it. var schemaForChildValidator = GetSchemaForType( schemaRepository: schemaFilterContext.SchemaRepository, schemaGenerator: schemaFilterContext.SchemaGenerator, schemaIdSelector: type => type.Name, parameterType: propertyRule.TypeToValidate); ApplyRulesToSchema( schema: schemaForChildValidator, schemaType: propertyRule.TypeToValidate, schemaPropertyNames: null, schemaFilterContext: schemaFilterContext, validator: childValidator, rules: rules, logger: logger); AddRulesFromIncludedValidators( schema: schemaForChildValidator, schemaFilterContext: schemaFilterContext, validator: childValidator, rules: rules, logger: logger); } } } } }
/// <summary> /// Applies the <see cref="OpenApiSchema.Nullable"/>, <see cref="OpenApiSchema.ReadOnly"/>, and <see cref="OpenApiSchema.WriteOnly"/> to <see cref="OpenApiSchema.Properties"/> of a given <paramref name="rootSchema"/>. /// </summary> /// <param name="rootSchema">The root <see cref="OpenApiSchema"/>.</param> /// <param name="context">The current <see cref="SchemaFilterContext"/>.</param> static void ApplyAttributesForRootSchema(OpenApiSchema rootSchema, SchemaFilterContext context) { // tune up the descendants rootSchema.Nullable = false; var rootSchemaId = GenerateSchemaId(context.Type); var rootRequestSchema = rootSchemaId.EndsWith("Request", StringComparison.Ordinal); var rootResponseSchema = rootSchemaId.EndsWith("Response", StringComparison.Ordinal); var isPutRequest = rootSchemaId.EndsWith("CreateRequest", StringComparison.Ordinal); Tuple <PropertyInfo, string, OpenApiSchema, IDictionary <string, OpenApiSchema> > GetTypeFromKvp(Type currentType, KeyValuePair <string, OpenApiSchema> kvp, IDictionary <string, OpenApiSchema> schemaDictionary) { var propertyInfo = currentType .GetProperties() .Single(x => x.Name.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase)); return(Tuple.Create( propertyInfo, kvp.Key, kvp.Value, schemaDictionary)); } var subSchemaStack = new Stack <Tuple <PropertyInfo, string, OpenApiSchema, IDictionary <string, OpenApiSchema> > >( rootSchema .Properties .Select( x => GetTypeFromKvp(context.Type, x, rootSchema.Properties)) .Where(x => x.Item3.Reference == null)); while (subSchemaStack.Count > 0) { var tuple = subSchemaStack.Pop(); var subSchema = tuple.Item3; var subSchemaPropertyInfo = tuple.Item1; if (subSchema.Properties != null && !subSchemaPropertyInfo .PropertyType .GetInterfaces() .Any(x => x == typeof(IEnumerable))) { foreach (var kvp in subSchema.Properties.Where(x => x.Value.Reference == null)) { subSchemaStack.Push(GetTypeFromKvp(subSchemaPropertyInfo.PropertyType, kvp, subSchema.Properties)); } } var attributes = subSchemaPropertyInfo .GetCustomAttributes(); var responsePresence = attributes .OfType <ResponseOptionsAttribute>() .FirstOrDefault() ?.Presence ?? FieldPresence.Required; var requestOptions = attributes .OfType <RequestOptionsAttribute>() .OrderBy(x => x.PutOnly) // Process PUTs last .ToList(); if (requestOptions.Any() && requestOptions.All(x => x.Presence == FieldPresence.Ignored && !x.PutOnly)) { subSchema.ReadOnly = true; } var subSchemaId = tuple.Item2; var subSchemaOwningDictionary = tuple.Item4; if (rootResponseSchema) { subSchema.Nullable = responsePresence == FieldPresence.Optional; if (responsePresence == FieldPresence.Ignored) { subSchemaOwningDictionary.Remove(subSchemaId); } } else if (rootRequestSchema) { subSchema.Nullable = true; var lastOptionWasIgnored = false; foreach (var requestOption in requestOptions) { var validForThisRequest = !requestOption.PutOnly || isPutRequest; if (!validForThisRequest) { continue; } lastOptionWasIgnored = false; switch (requestOption.Presence) { case FieldPresence.Ignored: lastOptionWasIgnored = true; break; case FieldPresence.Optional: subSchema.Nullable = true; break; case FieldPresence.Required: subSchema.Nullable = false; break; default: throw new InvalidOperationException($"Invalid FieldPresence: {requestOption.Presence}!"); } } if (lastOptionWasIgnored) { subSchemaOwningDictionary.Remove(subSchemaId); } } else if (responsePresence == FieldPresence.Required && requestOptions.All(x => x.Presence == FieldPresence.Required && !x.PutOnly)) { subSchema.Nullable = subSchemaId.Equals( nameof(TestMergeParameters.TargetCommitSha), StringComparison.OrdinalIgnoreCase) && rootSchemaId == nameof(TestMergeParameters); // special tactics } // otherwise, we have to assume it's a shared schema // use what Swagger thinks the nullability is by default } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { context.SchemaGenerator.GenerateSchema(typeof(PaginationMetaData), context.SchemaRepository); }
// public void Apply(Schema schema, SchemaFilterContext context) // { // var bookingId = Guid.NewGuid().ToString(); // // schema.Example = new PassengerAddedResource // { // ResourceLinks = new PassengerAddedResource.Links // { // Home = new Link<RestAirlineHomeResource>("api/home"), // Booking = new Link<BookingResource>("api/{bookingId}") // }, // ResourceCommands = new PassengerAddedResource.Commands // { // AddPassengerCommand = new AddPassengerCommand // { // Age = 23, // Name = "Test", // Email = "*****@*****.**", // BookingId = bookingId, // PassengerType = PassengerType.Male, // PostUrl = new Link<PassengerAddedResource>("api/{bookingId}/passenger") // }, // UpdatePassengerNameCommand = new UpdatePassengerNameCommand // { // Name = "new name", // BookingId = bookingId, // PassengerKey = "1", // PostUrl = new Link<PassengerNameUpdatedResource>( // "api/{bookingId}/passenger/{passengerKey}/name") // } // } // }; // } public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Example = new OpenApiObject(); }
public void Apply(Schema schema, SchemaFilterContext context) { var type = context.SystemType; schema.Example = GetExampleOrNullFor(context.SystemType); }
/// <summary> /// </summary> /// <param name="model"></param> /// <param name="context"></param> public void Apply(Schema model, SchemaFilterContext context) { var validator = _factory.GetValidator(context.SystemType); ValidatorDescription.AddRequires(model, context, validator); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { SwaggerEnum.Apply(schema, context, "original"); }
/// <inheritdoc/> public void Apply(Schema model, SchemaFilterContext context) { AddExtension(context.SystemType, model.Extensions); }
public void Apply(Schema schema, SchemaFilterContext context) { if (context.SystemType.GetTypeInfo().IsGenericType&& context.SystemType.GetTypeInfo().GetGenericTypeDefinition() == typeof(ResourceRequest <>)) { } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Extensions.Add("X-foo", new OpenApiString("bar")); schema.Extensions.Add("X-docName", new OpenApiString(context.DocumentName)); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Example = SchemaFiltersMock.GetGeekProfileResponse(); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { SwaggerEnum.Apply(schema, context, "lowercase"); }
void ApplyInternal(Operation operation, OperationFilterContext context) { if (operation.Parameters == null) { return; } var schemaIdSelector = _swaggerGenOptions.SchemaRegistryOptions.SchemaIdSelector ?? new SchemaRegistryOptions().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; } var key = modelMetadata.PropertyName; var validatorsForMember = validator.GetValidatorsForMemberIgnoreCase(key); var lazyLog = new LazyLog(_logger, logger => logger.LogDebug($"Applying FluentValidation rules to swagger schema for type '{parameterType}' from operation '{operation.OperationId}'.")); Schema schema = null; foreach (var propertyValidator in validatorsForMember) { foreach (var rule in _rules) { if (rule.Matches(propertyValidator)) { try { var schemaId = schemaIdSelector(parameterType); if (!context.SchemaRegistry.Definitions.TryGetValue(schemaId, out schema)) { schema = context.SchemaRegistry.GetOrRegister(parameterType); } if (schema.Properties == null && context.SchemaRegistry.Definitions.ContainsKey(schemaId)) { schema = context.SchemaRegistry.Definitions[schemaId]; } if (schema.Properties != null && schema.Properties.Count > 0) { lazyLog.LogOnce(); var schemaFilterContext = new SchemaFilterContext(parameterType, null, context.SchemaRegistry); // try to fix property casing (between property name and schema property name) var schemaProperty = schema.Properties.Keys.FirstOrDefault(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase)); if (schemaProperty != null) { key = schemaProperty; } rule.Apply(new RuleContext(schema, schemaFilterContext, key, propertyValidator)); _logger.LogDebug($"Rule '{rule.Name}' applied for property '{parameterType.Name}.{key}'."); } else { _logger.LogDebug($"Rule '{rule.Name}' skipped for property '{parameterType.Name}.{key}'."); } } catch (Exception e) { _logger.LogWarning(0, e, $"Error on apply rule '{rule.Name}' for property '{parameterType.Name}.{key}'."); } } } } if (schema?.Required != null) { operationParameter.Required = schema.Required.Contains(key, StringComparer.InvariantCultureIgnoreCase); } if (schema?.Properties != null) { var parameterSchema = operationParameter as PartialSchema; if (operationParameter != null) { if (schema.Properties.TryGetValue(key.ToLowerCamelCase(), out var property) || schema.Properties.TryGetValue(key, out property)) { parameterSchema.MinLength = property.MinLength; parameterSchema.MaxLength = property.MaxLength; parameterSchema.Pattern = property.Pattern; parameterSchema.Minimum = property.Minimum; parameterSchema.Maximum = property.Maximum; parameterSchema.ExclusiveMaximum = property.ExclusiveMaximum; parameterSchema.ExclusiveMinimum = property.ExclusiveMinimum; } } } } } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Example = SchemaFiltersMock.GetErrorResponse("InternalServerError"); }
public void Apply(Schema schema, SchemaFilterContext context) { Filter(schema, context); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Extensions.Add("X-foo", new OpenApiString("bar")); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Extensions.Add("X-property1", new OpenApiString("value")); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Properties.Remove("Id"); }
public void Apply(OpenApiSchema model, SchemaFilterContext context) { model.Properties = model.Properties.ToDictionary(d => d.Key.Substring(0, 1).ToLower() + d.Key.Substring(1), d => d.Value); }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { schema.Example = SchemaFiltersMock.GetErrorResponse("UnsupportedMediaType"); }
/// <summary> /// Apply schema operations for types in PTV.Domain.Model.Models.OpenApi namespace /// </summary> public void Apply(Schema schema, SchemaFilterContext context) { var typeInfo = context.SystemType.GetTypeInfo(); if (typeInfo.Namespace.Contains(namespaceRestriction)) { // Get all properties with validation attributes, exclude JsonIgnored, order by Type hierarchy var validatedProperties = GetOrderedProperties(context.SystemType); // For each property add attribute types which are meant to override base type definitions // such as MaxLengthAttribute (ie. declared overrides inherited) HashSet <string> nonAdditiveAttributesAdded = new HashSet <string>(); foreach (var property in validatedProperties) { // Get all property attributes (also inherited) for: // MaxLength, ListPropertyMaxLength, ListRequired and ListRegularExpression var attributes = property.GetCustomAttributes(true) .Where(a => a.GetType() == typeof(MaxLengthAttribute) || a.GetType() == typeof(ListPropertyMaxLengthAttribute) || a.GetType() == typeof(ListRequiredAttribute) || a.GetType() == typeof(ListRegularExpressionAttribute) ).ToList(); if (attributes.Count == 0) { continue; } // Get Json PropertyName if defined, otherwise use property name var propertyName = ((JsonPropertyAttribute)property.GetCustomAttribute(typeof(JsonPropertyAttribute)))?.PropertyName ?? property.Name; var definition = schema.Properties.Where(i => i.Key.ToLower() == propertyName.ToLower()).FirstOrDefault(); HashSet <string> nonAdditiveAttributes = new HashSet <string>(); foreach (var attribute in attributes) { var attributeTypeName = attribute.GetType().Name; var nonAdditiveMemberKey = propertyName + attributeTypeName; switch (attributeTypeName) { // Add attribute lengths to Swagger definition // Treat both MaxLengthAttributes similarly case nameof(ListPropertyMaxLengthAttribute): case nameof(MaxLengthAttribute): { if (nonAdditiveAttributesAdded.Contains(nonAdditiveMemberKey)) { continue; } var listAttribute = attribute as ListPropertyMaxLengthAttribute; // Get ListPropertyMaxLength OR MaxLength var length = listAttribute?.Length ?? (attribute as MaxLengthAttribute)?.Length; var listTypeValue = listAttribute?.TypeValue?.Trim(); if (definition.Value != null) { if (!nonAdditiveAttributes.Contains(nonAdditiveMemberKey)) { nonAdditiveAttributes.Add(nonAdditiveMemberKey); } definition.Value.Description += string.Format(" (Max.Length: {0}{1}).", length, !listTypeValue.IsNullOrEmpty() ? $" {listTypeValue}" : null); } } break; case nameof(ListRequiredAttribute): { // Add the key to schema required collection if (schema.Required == null) { schema.Required = new List <string>(); } schema.Required.Add(definition.Key); } break; case nameof(ListRegularExpressionAttribute): { // Add the regular expression pattern to definition if (definition.Value != null) { definition.Value.Pattern = (attribute as ListRegularExpressionAttribute)?.Pattern; } } break; } } nonAdditiveAttributes.ForEach(x => nonAdditiveAttributesAdded.Add(x)); } } }
public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var pet = new PetCreator().Create(); schema.Example = _objectBuilder.Build(pet); }