/// <summary> /// Used for testing against Controller/Actions /// </summary> /// <param name="controllerType"></param> /// <param name="actionName"></param> /// <param name="parameterDescriptions"></param> /// <param name="supportedResponseTypes"></param> /// <returns></returns> protected OperationFilterContext FilterContextFor(Type controllerType, string actionName, List <ApiParameterDescription> parameterDescriptions = null, List <ApiResponseType> supportedResponseTypes = null) { var apiDescription = new ApiDescription { ActionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = controllerType.GetTypeInfo(), MethodInfo = controllerType.GetMethod(actionName), } }; var schemaRepository = new SchemaRepository(); var methodInfo = controllerType.GetMethod(actionName); foreach (var parameterInfo in methodInfo.GetParameters()) { schemaRepository.GetOrAdd(parameterInfo.ParameterType, parameterInfo.ParameterType.SchemaDefinitionName(), () => new OpenApiSchema() { Reference = new OpenApiReference { Id = parameterInfo.Name } }); } return(FilterContextFor(apiDescription, new CamelCasePropertyNamesContractResolver(), parameterDescriptions, supportedResponseTypes, schemaRepository)); }
protected OperationFilterContext FilterContextFor(Type controllerType, string actionName, IContractResolver contractResolver, List <ApiParameterDescription> parameterDescriptions = null, List <ApiResponseType> supportedResponseTypes = null) { var apiDescription = new ApiDescription { ActionDescriptor = new ControllerActionDescriptor { ControllerTypeInfo = controllerType.GetTypeInfo(), MethodInfo = controllerType.GetMethod(actionName), } }; if (parameterDescriptions != null) { apiDescription.With(api => api.ParameterDescriptions, parameterDescriptions); } if (supportedResponseTypes != null) { apiDescription.With(api => api.SupportedResponseTypes, supportedResponseTypes); } var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = contractResolver }; var schemaOptions = new SchemaGeneratorOptions(); var schemaRepository = new SchemaRepository(); var methodInfo = controllerType.GetMethod(actionName); foreach (var parameterInfo in methodInfo.GetParameters()) { schemaRepository.GetOrAdd(parameterInfo.ParameterType, parameterInfo.ParameterType.SchemaDefinitionName(), () => new OpenApiSchema() { Reference = new OpenApiReference { Id = parameterInfo.Name } }); } return(new OperationFilterContext( apiDescription, new NewtonsoftSchemaGenerator(schemaOptions, jsonSerializerSettings), schemaRepository, (apiDescription.ActionDescriptor as ControllerActionDescriptor).MethodInfo)); }
private OpenApiSchema CreateObjectSchema(Type type, SchemaRepository schemaRepository) { if (!(_contractResolver.ResolveContract(type) is JsonObjectContract jsonObjectContract)) { throw new InvalidOperationException($"Type {type} does not resolve to a JsonObjectContract"); } var schema = new OpenApiSchema { Type = "object", Properties = new Dictionary <string, OpenApiSchema>(), Required = new SortedSet <string>(), AdditionalPropertiesAllowed = false }; // If it's a baseType with known subTypes, add the discriminator property if (_generatorOptions.GeneratePolymorphicSchemas && _generatorOptions.SubTypesResolver(type).Any()) { var discriminatorName = _generatorOptions.DiscriminatorSelector(type); schema.Properties.Add(discriminatorName, new OpenApiSchema { Type = "string" }); schema.Required.Add(discriminatorName); schema.Discriminator = new OpenApiDiscriminator { PropertyName = discriminatorName }; } foreach (var jsonProperty in jsonObjectContract.Properties) { if (jsonProperty.Ignored) { continue; } var customAttributes = jsonProperty.TryGetMemberInfo(out MemberInfo memberInfo) ? memberInfo.GetInlineOrMetadataTypeAttributes() : Enumerable.Empty <object>(); if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any()) { continue; } var required = jsonProperty.IsRequiredSpecified() ? jsonProperty.Required : jsonObjectContract.ItemRequired ?? Required.Default; schema.Properties[jsonProperty.PropertyName] = CreatePropertySchema(jsonProperty, customAttributes, required, schemaRepository); if (required == Required.Always || required == Required.AllowNull || customAttributes.OfType <RequiredAttribute>().Any()) { schema.Required.Add(jsonProperty.PropertyName); } } if (jsonObjectContract.ExtensionDataValueType != null) { schema.AdditionalProperties = _schemaGenerator.GenerateSchema(jsonObjectContract.ExtensionDataValueType, schemaRepository); schema.AdditionalPropertiesAllowed = true; } // If it's a known subType, reference the baseType for inheritied properties if (_generatorOptions.GeneratePolymorphicSchemas && type.BaseType != null && _generatorOptions.SubTypesResolver(type.BaseType).Contains(type)) { var baseType = type.BaseType; var baseSchemaReference = schemaRepository.GetOrAdd( type: baseType, schemaId: _generatorOptions.SchemaIdSelector(baseType), factoryMethod: () => CreateObjectSchema(baseType, schemaRepository)); var baseSchema = schemaRepository.Schemas[baseSchemaReference.Reference.Id]; schema.AllOf = new[] { baseSchemaReference }; foreach (var basePropertyName in baseSchema.Properties.Keys) { schema.Properties.Remove(basePropertyName); } } return(schema); }