/// <summary>Generates the properties for the given type and schema.</summary> /// <param name="typeDescription">The type desription.</param> /// <param name="schema">The properties</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns></returns> protected override void GenerateObject(JsonSchema schema, JsonTypeDescription typeDescription, JsonSchemaResolver schemaResolver) { // iiQ Custom // .. Guards against "Item" is registered multiple times exception within base.GenerateObject if (typeDescription?.ContextualType?.Type?.FullName == "MongoDB.Bson.BsonValue" || (typeDescription?.ContextualType?.Type?.FullName ?? "").StartsWith("System.")) { return; } if (_isRootType) { _isRootType = false; base.GenerateObject(schema, typeDescription, schemaResolver); _isRootType = true; } else { if (!schemaResolver.HasSchema(typeDescription.ContextualType.OriginalType, false)) { _isRootType = true; Generate(typeDescription.ContextualType.OriginalType, schemaResolver); _isRootType = false; } schema.Reference = schemaResolver.GetSchema(typeDescription.ContextualType.OriginalType, false); } }
private bool IsFileArray(Type type, JsonTypeDescription typeInfo) { var isFormFileCollection = type.Name == "IFormFileCollection"; var isFileArray = typeInfo.Type == JsonObjectType.Array && type.GenericTypeArguments.Any() && _settings.ReflectionService.GetDescription(type.GenericTypeArguments[0], null, _settings).Type == JsonObjectType.File; return(isFormFileCollection || isFileArray); }
private OpenApiParameter TryAddFileParameter( OperationProcessorContext context, JsonTypeDescription typeInfo, ContextualParameterInfo contextualParameter) { var isFileArray = IsFileArray(contextualParameter.Type, typeInfo); var hasSwaggerFileAttribute = contextualParameter.Attributes .FirstAssignableToTypeNameOrDefault("SwaggerFileAttribute", TypeNameStyle.Name) != null; if (typeInfo.Type == JsonObjectType.File || typeInfo.Format == JsonFormatStrings.Binary || hasSwaggerFileAttribute || isFileArray) { return(AddFileParameter(context, contextualParameter, isFileArray)); } return(null); }
private async Task <SwaggerParameter> TryAddFileParameterAsync( OperationProcessorContext context, JsonTypeDescription info, ParameterInfo parameter) { var isFileArray = IsFileArray(parameter.ParameterType, info); var attributes = parameter.GetCustomAttributes() .Union(parameter.ParameterType.GetTypeInfo().GetCustomAttributes()); var hasSwaggerFileAttribute = attributes.Any(a => a.GetType().IsAssignableTo("SwaggerFileAttribute", TypeNameStyle.Name)); if (info.Type == JsonObjectType.File || hasSwaggerFileAttribute || isFileArray) { return(await AddFileParameterAsync(context, parameter, isFileArray).ConfigureAwait(false)); } return(null); }
/// <summary>Generates an enumeration in the given schema.</summary> /// <param name="schema">The schema.</param> /// <param name="typeDescription">The type description.</param> protected override void GenerateEnum(JsonSchema schema, JsonTypeDescription typeDescription) { var contextualType = typeDescription.ContextualType; schema.Type = typeDescription.Type; schema.Enumeration.Clear(); schema.EnumerationNames.Clear(); schema.IsFlagEnumerable = contextualType.GetTypeAttribute <FlagsAttribute>() != null; var underlyingType = Enum.GetUnderlyingType(contextualType.Type); foreach (var enumName in Enum.GetNames(contextualType.Type)) { if (typeDescription.Type == JsonObjectType.Integer) { var value = Convert.ChangeType(Enum.Parse(contextualType.Type, enumName), underlyingType); schema.Enumeration.Add(value); } else { // EnumMember only checked if StringEnumConverter is used var attributes = contextualType.TypeInfo.GetDeclaredField(enumName).GetCustomAttributes(typeof(EnumMemberAttribute)); var enumMemberAttribute = (EnumMemberAttribute)attributes.FirstOrDefault(); if (enumMemberAttribute != null && !string.IsNullOrEmpty(enumMemberAttribute.Value)) { schema.Enumeration.Add(enumMemberAttribute.Value); } else { schema.Enumeration.Add(enumName); } } schema.EnumerationNames.Add(enumName); } if (typeDescription.Type == JsonObjectType.Integer && this.Settings.GenerateEnumMappingDescription) { schema.Description = (schema.Description + "\n\n" + string.Join("\n", schema.Enumeration.Select((e, i) => e + " = " + schema.EnumerationNames[i]))).Trim(); } }
private bool IsFileArray(Type type, JsonTypeDescription typeInfo) { var isFormFileCollection = type.Name == "IFormFileCollection"; if (isFormFileCollection) { return(true); } if (typeInfo.Type == JsonObjectType.Array && type.GenericTypeArguments.Any()) { var description = _settings.ReflectionService.GetDescription(type.GenericTypeArguments[0].ToContextualType(), _settings); if (description.Type == JsonObjectType.File || description.Format == JsonFormatStrings.Binary) { return(true); } } return(false); }
/// <summary>Generates the properties for the given type and schema.</summary> /// <param name="typeDescription">The type desription.</param> /// <param name="schema">The properties</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns></returns> protected override void GenerateObject(JsonSchema schema, JsonTypeDescription typeDescription, JsonSchemaResolver schemaResolver) { if (_isRootType) { _isRootType = false; base.GenerateObject(schema, typeDescription, schemaResolver); _isRootType = true; } else { if (!schemaResolver.HasSchema(typeDescription.ContextualType.OriginalType, false)) { _isRootType = true; Generate(typeDescription.ContextualType.OriginalType, schemaResolver); _isRootType = false; } schema.Reference = schemaResolver.GetSchema(typeDescription.ContextualType.OriginalType, false); } }
/// <summary>Generates the properties for the given type and schema.</summary> /// <param name="type">The types.</param> /// <param name="typeDescription">The type desription.</param> /// <param name="schema">The properties</param> /// <param name="schemaResolver">The schema resolver.</param> /// <returns></returns> protected override async Task GenerateObjectAsync(Type type, JsonTypeDescription typeDescription, JsonSchema4 schema, JsonSchemaResolver schemaResolver) { if (_isRootType) { _isRootType = false; await base.GenerateObjectAsync(type, typeDescription, schema, schemaResolver); _isRootType = true; } else { if (!schemaResolver.HasSchema(type, false)) { _isRootType = true; await GenerateAsync(type, schemaResolver); _isRootType = false; } schema.Reference = schemaResolver.GetSchema(type, false); } }
private OpenApiParameter CreatePrimitiveSwaggerParameter(ContextualType contextualParameter, JsonTypeDescription typeDescription) { OpenApiParameter operationParameter; if (typeDescription.RequiresSchemaReference(_settings.TypeMappers)) { var referencedSchema = _settings.SchemaGenerator.Generate(contextualParameter, _schemaResolver); operationParameter = new OpenApiParameter { Type = typeDescription.Type, CustomSchema = new JsonSchema { Reference = referencedSchema.ActualSchema } }; // Copy enumeration for compatibility with other tools which do not understand x-schema. // The enumeration will be ignored by NSwag and only the x-schema is processed if (referencedSchema.ActualSchema.IsEnumeration) { operationParameter.Enumeration.Clear(); foreach (var item in referencedSchema.ActualSchema.Enumeration) { operationParameter.Enumeration.Add(item); } } _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter, typeDescription); } else { operationParameter = _settings.SchemaGenerator.Generate <OpenApiParameter>(contextualParameter, _schemaResolver); _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter, typeDescription); } return(operationParameter); }
private OpenApiParameter CreatePrimitiveOpenApiParameter(ContextualType contextualParameter, JsonTypeDescription typeDescription) { OpenApiParameter operationParameter; if (typeDescription.RequiresSchemaReference(_settings.TypeMappers)) { operationParameter = new OpenApiParameter(); operationParameter.Schema = new JsonSchema(); _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter.Schema, typeDescription); var referencedSchema = _settings.SchemaGenerator.Generate(contextualParameter, _schemaResolver); var hasSchemaAnnotations = JsonConvert.SerializeObject(operationParameter.Schema) != "{}"; if (hasSchemaAnnotations || typeDescription.IsNullable) { operationParameter.Schema.IsNullableRaw = true; operationParameter.Schema.OneOf.Add(new JsonSchema { Reference = referencedSchema.ActualSchema }); } else { operationParameter.Schema = new JsonSchema { Reference = referencedSchema.ActualSchema }; } } else { operationParameter = new OpenApiParameter(); operationParameter.Schema = _settings.SchemaGenerator.GenerateWithReferenceAndNullability <JsonSchema>( contextualParameter, typeDescription.IsNullable, _schemaResolver); _settings.SchemaGenerator.ApplyDataAnnotations(operationParameter.Schema, typeDescription); } return(operationParameter); }
private OpenApiParameter AddPrimitiveParametersFromUri( OperationProcessorContext context, string httpPath, string name, ContextualParameterInfo contextualParameter, JsonTypeDescription typeDescription) { var operation = context.OperationDescription.Operation; if (typeDescription.Type.HasFlag(JsonObjectType.Array)) { var parameterDocumentation = contextualParameter.GetDescription(_settings); var operationParameter = context.DocumentGenerator.CreatePrimitiveParameter( name, parameterDocumentation, contextualParameter); operationParameter.Kind = OpenApiParameterKind.Query; operation.Parameters.Add(operationParameter); return(operationParameter); } else { foreach (var contextualProperty in contextualParameter.Type.GetContextualProperties()) { if (contextualProperty.ContextAttributes.Select(a => a.GetType()).All(a => !a.IsAssignableToTypeName("SwaggerIgnoreAttribute", TypeNameStyle.Name) && !a.IsAssignableToTypeName("JsonIgnoreAttribute", TypeNameStyle.Name))) { var fromQueryAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().Name == "FromQueryAttribute"); var propertyName = fromQueryAttribute.TryGetPropertyValue <string>("Name") ?? context.SchemaGenerator.GetPropertyName(null, contextualProperty); dynamic fromRouteAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromRouteAttribute"); if (fromRouteAttribute != null && !string.IsNullOrEmpty(fromRouteAttribute?.Name)) { propertyName = fromRouteAttribute?.Name; } dynamic fromHeaderAttribute = contextualProperty.ContextAttributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromHeaderAttribute"); if (fromHeaderAttribute != null && !string.IsNullOrEmpty(fromHeaderAttribute?.Name)) { propertyName = fromHeaderAttribute?.Name; } var propertySummary = contextualProperty.PropertyInfo.GetXmlDocsSummary(_settings.ResolveExternalXmlDocumentation); var operationParameter = context.DocumentGenerator.CreatePrimitiveParameter(propertyName, propertySummary, contextualProperty.AccessorType); // TODO: Check if required can be controlled with mechanisms other than RequiredAttribute var parameterInfo = _settings.ReflectionService.GetDescription(contextualProperty.AccessorType, _settings); var isFileArray = IsFileArray(contextualProperty.AccessorType.Type, parameterInfo); if (parameterInfo.Type == JsonObjectType.File || isFileArray) { InitializeFileParameter(operationParameter, isFileArray); } else if (fromRouteAttribute != null || httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + "}") || httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + ":")) { operationParameter.Kind = OpenApiParameterKind.Path; operationParameter.IsNullableRaw = false; operationParameter.IsRequired = true; // Path is always required => property not needed } else if (fromHeaderAttribute != null) { operationParameter.Kind = OpenApiParameterKind.Header; } else { operationParameter.Kind = OpenApiParameterKind.Query; } operation.Parameters.Add(operationParameter); } } return(null); } }
private async Task AddPrimitiveParametersFromUriAsync(OperationProcessorContext context, string httpPath, string name, ParameterInfo parameter, JsonTypeDescription typeDescription) { var operation = context.OperationDescription.Operation; if (typeDescription.Type.HasFlag(JsonObjectType.Array)) { var attributes = parameter.GetCustomAttributes(); var parameterDocumentation = await parameter.GetDescriptionAsync(attributes).ConfigureAwait(false); var operationParameter = await context.SwaggerGenerator.CreatePrimitiveParameterAsync( name, parameterDocumentation, parameter.ParameterType, attributes).ConfigureAwait(false); operationParameter.Kind = SwaggerParameterKind.Query; operation.Parameters.Add(operationParameter); } else { foreach (var property in parameter.ParameterType.GetRuntimeProperties()) { var attributes = property.GetCustomAttributes().ToList(); if (attributes.All(a => a.GetType().Name != "SwaggerIgnoreAttribute" && a.GetType().Name != "JsonIgnoreAttribute")) { var fromQueryAttribute = attributes.SingleOrDefault(a => a.GetType().Name == "FromQueryAttribute"); var propertyName = fromQueryAttribute.TryGetPropertyValue <string>("Name") ?? context.SchemaGenerator.GetPropertyName(null, property); dynamic fromRouteAttribute = attributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromRouteAttribute"); if (fromRouteAttribute != null && !string.IsNullOrEmpty(fromRouteAttribute?.Name)) { propertyName = fromRouteAttribute?.Name; } dynamic fromHeaderAttribute = attributes.SingleOrDefault(a => a.GetType().FullName == "Microsoft.AspNetCore.Mvc.FromHeaderAttribute"); if (fromHeaderAttribute != null && !string.IsNullOrEmpty(fromHeaderAttribute?.Name)) { propertyName = fromHeaderAttribute?.Name; } var propertySummary = await property.GetXmlSummaryAsync().ConfigureAwait(false); var operationParameter = await context.SwaggerGenerator.CreatePrimitiveParameterAsync( propertyName, propertySummary, property.PropertyType, attributes).ConfigureAwait(false); // TODO: Check if required can be controlled with mechanisms other than RequiredAttribute var parameterInfo = _settings.ReflectionService.GetDescription(property.PropertyType, attributes, _settings); var isFileArray = IsFileArray(property.PropertyType, parameterInfo); if (parameterInfo.Type == JsonObjectType.File || isFileArray) { InitializeFileParameter(operationParameter, isFileArray); } else if (fromRouteAttribute != null || httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + "}") || httpPath.ToLowerInvariant().Contains("{" + propertyName.ToLower() + ":")) { operationParameter.Kind = SwaggerParameterKind.Path; operationParameter.IsNullableRaw = false; operationParameter.IsRequired = true; // Path is always required => property not needed } else if (fromHeaderAttribute != null) { operationParameter.Kind = SwaggerParameterKind.Header; } else { operationParameter.Kind = SwaggerParameterKind.Query; } operation.Parameters.Add(operationParameter); } } } }