private static void applyValueLookupForDynamicProperties(Schema schemaProperty, PropertyInfo propertyInfo)
        {
            // Applies dynamic value lookup for the current property (if DynamicValueLookupAttribute is present)

            if (schemaProperty == null || propertyInfo == null)
            {
                return;
            }

            var valueLookupInfo = propertyInfo.GetCustomAttribute <DynamicValueLookupAttribute>();

            if (valueLookupInfo == null)
            {
                return;
            }

            var valueLookup = new DynamicValuesModel()
            {
                Parameters      = ParsingUtility.ParseJsonOrUrlEncodedParams(valueLookupInfo.Parameters),
                ValueCollection = valueLookupInfo.ValueCollection,
                ValuePath       = valueLookupInfo.ValuePath,
                ValueTitle      = valueLookupInfo.ValueTitle
            };

            valueLookup.OperationId = valueLookupInfo.LookupOperation;

            schemaProperty.SetValueLookup(valueLookup);
        }
Example #2
0
        private static void applyValueLookupForDynamicParameters(Operation operation, ApiDescription apiDescription)
        {
            if (operation == null || apiDescription == null)
            {
                return;
            }

            var lookupParameters = from p in apiDescription.ParameterDescriptions
                                   let valueLookupInfo = p.ParameterDescriptor.GetFirstOrDefaultCustomAttribute <DynamicValueLookupAttribute>()
                                                         where valueLookupInfo != null
                                                         select new
            {
                SwaggerParameter = operation.parameters.FirstOrDefault(param => param.name == p.Name),
                Parameter        = p,
                ValueLookupInfo  = valueLookupInfo
            };

            if (!lookupParameters.Any())
            {
                return;
            }

            foreach (var param in lookupParameters)
            {
                var valueLookup = new DynamicValuesModel()
                {
                    Parameters      = ParsingUtility.ParseJsonOrUrlEncodedParams(param.ValueLookupInfo.Parameters),
                    ValueCollection = param.ValueLookupInfo.ValueCollection,
                    ValuePath       = param.ValueLookupInfo.ValuePath,
                    ValueTitle      = param.ValueLookupInfo.ValueTitle
                };

                valueLookup.OperationId =
                    apiDescription.ResolveOperationIdForSiblingAction(
                        param.ValueLookupInfo.LookupOperation,
                        valueLookup.Parameters.Properties().Select(p => p.Name).ToArray());

                param.SwaggerParameter.SetValueLookup(valueLookup);
            }
        }
        private static void applySchemaLookupForDynamicModels(Schema schema, SchemaRegistry schemaRegistry, Type type)
        {
            if (schema == null || type == null)
            {
                return;
            }

            var dynamicSchemaInfo = type.GetCustomAttributes <DynamicSchemaLookupAttribute>().FirstOrDefault();

            if (null == dynamicSchemaInfo)
            {
                return;
            }

            var schemaLookupSettings = new DynamicSchemaModel()
            {
                OperationId = dynamicSchemaInfo.LookupOperation,
                Parameters  = ParsingUtility.ParseJsonOrUrlEncodedParams(dynamicSchemaInfo.Parameters),
                ValuePath   = dynamicSchemaInfo.ValuePath
            };

            // Swashbuckle should end up generating a ref schema in this case already,
            // in which case all that is necessary is to apply the vendor extensions and
            // get out of this method
            if (type.BaseType == typeof(object))
            {
                schema.SetSchemaLookup(schemaLookupSettings);
                return;
            }

            // Determine if the dynamic schema already appears in the schema registry
            // if it appears, we will reference it's definition and make sure it has the
            // vendor extension applied
            if (schemaRegistry.Definitions.ContainsKey(type.Name))
            {
                schemaRegistry.Definitions[type.Name].SetSchemaLookup(schemaLookupSettings);
            }
            else
            {
                // Dynamic schema hasn't been registered yet, let's do that to make sure
                // the schema doesn't get inlined (since the settings will be common for the type
                // given that the attribute appears at the class-level)
                var dynamicSchema = new Schema()
                {
                    additionalProperties = schema.additionalProperties,
                    allOf            = schema.allOf,
                    @default         = schema.@default,
                    description      = schema.description,
                    discriminator    = schema.discriminator,
                    @enum            = schema.@enum,
                    example          = schema.example,
                    exclusiveMaximum = schema.exclusiveMaximum,
                    exclusiveMinimum = schema.exclusiveMinimum,
                    externalDocs     = schema.externalDocs,
                    format           = schema.format,
                    items            = schema.items,
                    maximum          = schema.maximum,
                    maxItems         = schema.maxItems,
                    maxLength        = schema.maxLength,
                    maxProperties    = schema.maxProperties,
                    minimum          = schema.minimum,
                    minItems         = schema.minItems,
                    minLength        = schema.minLength,
                    minProperties    = schema.minProperties,
                    multipleOf       = schema.multipleOf,
                    pattern          = schema.pattern,
                    properties       = schema.properties,
                    readOnly         = schema.readOnly,
                    @ref             = schema.@ref,
                    required         = schema.required,
                    title            = schema.title,
                    type             = schema.type,
                    uniqueItems      = schema.uniqueItems,
                    xml = schema.xml
                };

                dynamicSchema.SetSchemaLookup(schemaLookupSettings);
                dynamicSchema.properties = dynamicSchema.properties ?? new Dictionary <string, Schema>();

                schemaRegistry.Definitions.Add(type.Name, dynamicSchema);
            }

            // Let's make sure the current schema points to the definition that is registered
            // and doesn't get inlined
            if (string.IsNullOrWhiteSpace(schema.@ref))
            {
                schema.@ref       = $"#/{nameof(schemaRegistry.Definitions).ToLower(CultureInfo.InvariantCulture)}/{type.Name}";
                schema.type       = null;
                schema.properties = null;
            }
        }