/// <summary>
        /// Gets the OpenAPI reference ID.
        /// </summary>
        /// <param name="type"><see cref="Type"/> instance.</param>
        /// <param name="isDictionary">Value indicating whether the type is <see cref="Dictionary{TKey, TValue}"/> or not.</param>
        /// <param name="isList">Value indicating whether the type is <see cref="List{T}"/> or not.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the OpenAPI reference ID.</returns>
        public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bool isList, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (isDictionary)
            {
                var name = type.Name.EndsWith("[]") ? "Dictionary_" + type.GetOpenApiSubTypeName(namingStrategy) : type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy);
                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }
            if (isList)
            {
                var name = type.Name.EndsWith("[]") ? "List_" + type.GetOpenApiSubTypeName(namingStrategy) : type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy);
                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }

            if (type.IsGenericType)
            {
                return(namingStrategy.GetPropertyName(type.Name.Split('`').First(), false) + "_" +
                       string.Join("_", type.GenericTypeArguments.Select(a => namingStrategy.GetPropertyName(a.Name, false))));
            }

            return(namingStrategy.GetPropertyName(type.Name, hasSpecifiedName: false));
        }
示例#2
0
        /// <summary>
        /// Gets the name of the sub type of the given <see cref="Type"/>.
        /// </summary>
        /// <param name="type"><see cref="Type"/> instance.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the name of the sub type of the given <see cref="Type"/>.</returns>
        public static string GetOpenApiSubTypeName(this Type type, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (type.IsDictionaryType())
            {
                var name = type.GetGenericArguments()[1].Name;

                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }

            if (type.BaseType == typeof(Array))
            {
                var name = type.GetElementType().Name;

                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }

            if (type.IsArrayType())
            {
                var name = type.GetGenericArguments()[0].Name;

                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }

            return(null);
        }
示例#3
0
        /// <inheritdoc />
        public IDocument Build(Assembly assembly, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            var paths = new OpenApiPaths();

            var methods = this._helper.GetHttpTriggerMethods(assembly);

            foreach (var method in methods)
            {
                var trigger = this._helper.GetHttpTriggerAttribute(method);
                if (trigger.IsNullOrDefault())
                {
                    continue;
                }

                var function = this._helper.GetFunctionNameAttribute(method);
                if (function.IsNullOrDefault())
                {
                    continue;
                }

                var path = this._helper.GetHttpEndpoint(function, trigger);
                if (path.IsNullOrWhiteSpace())
                {
                    continue;
                }

                var verb = this._helper.GetHttpVerb(trigger);

                var item       = this._helper.GetOpenApiPath(path, paths);
                var operations = item.Operations;

                var operation = this._helper.GetOpenApiOperation(method, function, verb);
                if (operation.IsNullOrDefault())
                {
                    continue;
                }

                operation.Parameters  = this._helper.GetOpenApiParameters(method, trigger);
                operation.RequestBody = this._helper.GetOpenApiRequestBody(method);
                operation.Responses   = this._helper.GetOpenApiResponseBody(method);

                operations[verb] = operation;
                item.Operations  = operations;

                paths[path] = item;
            }

            this._document.Paths = paths;
            this._document.Components.Schemas         = this._helper.GetOpenApiSchemas(methods, namingStrategy);
            this._document.Components.SecuritySchemes = this._helper.GetOpenApiSecuritySchemes();

            return(this);
        }
示例#4
0
        /// <summary>
        /// Gets the type name applied by <see cref="NamingStrategy"/>.
        /// </summary>
        /// <param name="type">Type to check.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the type name applied by <see cref="NamingStrategy"/>.</returns>
        public static string GetOpenApiTypeName(this Type type, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            var typeName = type.IsGenericType ? type.GetOpenApiGenericRootName() : type.Name;
            var name     = namingStrategy.GetPropertyName(typeName, hasSpecifiedName: false);

            return(name);
        }
        /// <summary>
        /// Gets the display name of the enum value.
        /// </summary>
        /// <param name="enum">Enum value.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Display name of the enum value.</returns>
        public static string ToDisplayName(this Enum @enum, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            var type   = @enum.GetType();
            var member = type.GetMember(@enum.ToString()).First();

            return(member.ToDisplayName(namingStrategy));
        }
        /// <summary>
        /// Gets the display name of the enum value.
        /// </summary>
        /// <param name="enum">Enum value.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Display name of the enum value.</returns>
        public static string ToDisplayName(this Enum @enum, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            var type      = @enum.GetType();
            var member    = type.GetMember(@enum.ToString()).First();
            var attribute = member.GetCustomAttribute <DisplayAttribute>(inherit: false);
            var name      = attribute == null? @enum.ToString() : attribute.Name;

            return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
        }
        /// <summary>
        /// Converts <see cref="OpenApiPayloadAttribute"/> to <see cref="OpenApiMediaType"/>.
        /// </summary>
        /// <typeparam name="T">Type of payload attribute inheriting <see cref="OpenApiPayloadAttribute"/>.</typeparam>
        /// <param name="attribute">OpenApi payload attribute.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance to create the JSON schema from .NET Types.</param>
        /// <param name="collection"><see cref="VisitorCollection"/> instance.</param>
        /// <returns><see cref="OpenApiMediaType"/> instance.</returns>
        public static OpenApiMediaType ToOpenApiMediaType <T>(this T attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null) where T : OpenApiPayloadAttribute
        {
            attribute.ThrowIfNullOrDefault();

            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (collection.IsNullOrDefault())
            {
                collection = VisitorCollection.CreateInstance();
            }

            var type = attribute.BodyType;

            // Generate schema based on the type.
            var schema = collection.PayloadVisit(type, namingStrategy);

            // Add deprecated attribute.
            if (attribute is OpenApiRequestBodyAttribute)
            {
                schema.Deprecated = (attribute as OpenApiRequestBodyAttribute).Deprecated;
            }
            if (attribute is OpenApiResponseWithBodyAttribute)
            {
                schema.Deprecated = (attribute as OpenApiResponseWithBodyAttribute).Deprecated;
            }

            // For array and dictionary object, the reference has already been added by the visitor.
            if (type.IsReferentialType() && !type.IsOpenApiNullable() && !type.IsOpenApiArray() && !type.IsOpenApiDictionary())
            {
                var reference = new OpenApiReference()
                {
                    Type = ReferenceType.Schema,
                    Id   = attribute.BodyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
                };

                schema.Reference = reference;
            }

            var mediaType = new OpenApiMediaType()
            {
                Schema = schema
            };

            return(mediaType);
        }
        /// <summary>
        /// Gets the Open API reference ID.
        /// </summary>
        /// <param name="type"><see cref="Type"/> instance.</param>
        /// <param name="isDictionary">Value indicating whether the type is <see cref="Dictionary{TKey, TValue}"/> or not.</param>
        /// <param name="isList">Value indicating whether the type is <see cref="List{T}"/> or not.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the Open API reference ID.</returns>
        public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bool isList, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (isDictionary || isList)
            {
                var name = type.GetOpenApiSubTypeName(namingStrategy);

                return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
            }

            return(namingStrategy.GetPropertyName(type.Name, hasSpecifiedName: false));
        }
        /// <summary>
        /// Gets the name from <see cref="JsonPropertyAttribute"/> instance.
        /// </summary>
        /// <param name="element"><see cref="PropertyInfo"/> instance.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the name from <see cref="JsonPropertyAttribute"/> instance.</returns>
        public static string GetJsonPropertyName(this PropertyInfo element, NamingStrategy namingStrategy = null)
        {
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (element.HasJsonPropertyAttribute())
            {
                var name = element.GetCustomAttribute <JsonPropertyAttribute>().PropertyName ?? namingStrategy.GetPropertyName(element.Name, hasSpecifiedName: false);

                return(name);
            }

            return(namingStrategy.GetPropertyName(element.Name, hasSpecifiedName: false));
        }
        /// <summary>
        /// Converts the given <see cref="Type"/> instance to the list of underlying enum name.
        /// </summary>
        /// <param name="type"><see cref="Type"/> instance.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Returns the list of underlying enum name.</returns>
        public static List <IOpenApiAny> ToOpenApiStringCollection(this Type type, NamingStrategy namingStrategy = null)
        {
            if (!type.IsUnflaggedEnumType())
            {
                return(null);
            }

            // namingStrategy null check
            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }
            // namingStrategy null check

            var members = type.GetMembers(BindingFlags.Public | BindingFlags.Static);
            var names   = members.Select(p => p.ToDisplayName(namingStrategy));

            return(names.Select(p => (IOpenApiAny) new OpenApiString(p))
                   .ToList());
        }
示例#11
0
        /// <summary>
        /// Gets the display name of the enum value.
        /// </summary>
        /// <param name="element"><see cref="MemberInfo"/> instance.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <returns>Display name of the enum value.</returns>
        public static string ToDisplayName(this MemberInfo element, NamingStrategy namingStrategy = null)
        {
            element.ThrowIfNullOrDefault();

            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            var displayAttribute    = element.GetCustomAttribute <DisplayAttribute>(inherit: false);
            var enumMemberAttribute = element.GetCustomAttribute <EnumMemberAttribute>(inherit: false);

            // EnumMemberAttribute takes precedence to DisplayAttribute
            var name = !enumMemberAttribute.IsNullOrDefault()
                       ? enumMemberAttribute.Value
                       : (!displayAttribute.IsNullOrDefault()
                          ? displayAttribute.Name
                          : element.Name);

            return(namingStrategy.GetPropertyName(name, hasSpecifiedName: false));
        }
示例#12
0
        /// <summary>
        /// Converts <see cref="OpenApiParameterAttribute"/> to <see cref="OpenApiParameter"/>.
        /// </summary>
        /// <param name="attribute"><see cref="OpenApiParameterAttribute"/> instance.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
        /// <param name="collection"><see cref="VisitorCollection"/> instance.</param>
        /// <returns><see cref="OpenApiParameter"/> instance.</returns>
        public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null)
        {
            attribute.ThrowIfNullOrDefault();

            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (collection.IsNullOrDefault())
            {
                collection = VisitorCollection.CreateInstance();
            }

            var type = attribute.Type;

            var schema = collection.ParameterVisit(type, namingStrategy);

            var parameter = new OpenApiParameter()
            {
                Name        = attribute.Name,
                Description = attribute.Description,
                Required    = attribute.Required,
                In          = attribute.In,
                Schema      = schema
            };

            if (type.IsOpenApiArray())
            {
                if (attribute.In == ParameterLocation.Path)
                {
                    parameter.Style   = ParameterStyle.Simple;
                    parameter.Explode = false;
                }

                if (attribute.In == ParameterLocation.Query)
                {
                    parameter.Style = attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Comma
                                      ? ParameterStyle.Form
                                      : (attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Space
                                         ? ParameterStyle.SpaceDelimited
                                         : ParameterStyle.PipeDelimited);
                    parameter.Explode = attribute.CollectionDelimiter == OpenApiParameterCollectionDelimiterType.Comma
                                        ? attribute.Explode
                                        : false;
                }
            }

            if (!string.IsNullOrWhiteSpace(attribute.Summary))
            {
                var summary = new OpenApiString(attribute.Summary);

                parameter.Extensions.Add("x-ms-summary", summary);
            }

            if (attribute.Visibility != OpenApiVisibilityType.Undefined)
            {
                var visibility = new OpenApiString(attribute.Visibility.ToDisplayName());

                parameter.Extensions.Add("x-ms-visibility", visibility);
            }

            return(parameter);
        }
示例#13
0
        /// <summary>
        /// Converts <see cref="OpenApiPayloadAttribute"/> to <see cref="OpenApiMediaType"/>.
        /// </summary>
        /// <typeparam name="T">Type of payload attribute inheriting <see cref="OpenApiPayloadAttribute"/>.</typeparam>
        /// <param name="attribute">OpenApi payload attribute.</param>
        /// <param name="namingStrategy"><see cref="NamingStrategy"/> instance to create the JSON schema from .NET Types.</param>
        /// <param name="collection"><see cref="VisitorCollection"/> instance.</param>
        /// <param name="version">OpenAPI spec version.</param>
        /// <returns><see cref="OpenApiMediaType"/> instance.</returns>
        public static OpenApiMediaType ToOpenApiMediaType <T>(this T attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null, OpenApiVersionType version = OpenApiVersionType.V2) where T : OpenApiPayloadAttribute
        {
            attribute.ThrowIfNullOrDefault();

            if (namingStrategy.IsNullOrDefault())
            {
                namingStrategy = new DefaultNamingStrategy();
            }

            if (collection.IsNullOrDefault())
            {
                collection = VisitorCollection.CreateInstance();
            }

            var type = attribute.BodyType;

            // Generate schema based on the type.
            var schema = collection.PayloadVisit(type, namingStrategy);

            // Add deprecated attribute.
            if (attribute is OpenApiRequestBodyAttribute)
            {
                schema.Deprecated = (attribute as OpenApiRequestBodyAttribute).Deprecated;
            }
            if (attribute is OpenApiResponseWithBodyAttribute)
            {
                schema.Deprecated = (attribute as OpenApiResponseWithBodyAttribute).Deprecated;
            }

            // For array and dictionary object, the reference has already been added by the visitor.
            if (type.IsReferentialType() && !type.IsOpenApiNullable() && !type.IsOpenApiArray() && !type.IsOpenApiDictionary())
            {
                var reference = new OpenApiReference()
                {
                    Type = ReferenceType.Schema,
                    Id   = attribute.BodyType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
                };

                schema.Reference = reference;
            }

            var mediaType = new OpenApiMediaType()
            {
                Schema = schema
            };

            if (attribute.Example.IsNullOrDefault())
            {
                return(mediaType);
            }

            if (!attribute.Example.HasInterface("IOpenApiExample`1"))
            {
                return(mediaType);
            }

            var example  = (dynamic)Activator.CreateInstance(attribute.Example);
            var examples = (IDictionary <string, OpenApiExample>)example.Build(namingStrategy).Examples;

            mediaType.Examples = examples;
            if (version == OpenApiVersionType.V2)
            {
                mediaType.Example = examples.First().Value.Value;
            }

            return(mediaType);
        }