Esempio n. 1
0
        public static void ProcessFields(Type definitionType, DefinitionSchema schema, IList <string> hiddenTags,
                                         Stack <Type> typesStack)
        {
            var properties = definitionType.GetFields();

            foreach (var fieldInfo in properties)
            {
                DefinitionProperty prop = ProcessField(fieldInfo, hiddenTags, typesStack);

                if (prop == null)
                {
                    continue;
                }

                if (prop.TypeFormat.Type == ParameterType.Array)
                {
                    Type propType = fieldInfo.FieldType;

                    Type t = propType.GetElementType() ?? DefinitionsBuilder.GetEnumerableType(propType);

                    if (t != null)
                    {
                        //prop.TypeFormat = new TypeFormat(prop.TypeFormat.Type, HttpUtility.HtmlEncode(t.FullName));
                        prop.TypeFormat = new TypeFormat(prop.TypeFormat.Type, null);

                        TypeFormat st = Helpers.MapSwaggerType(t);
                        if (st.Type == ParameterType.Array || st.Type == ParameterType.Object)
                        {
                            prop.Items.TypeFormat = new TypeFormat(ParameterType.Unknown, null);
                            prop.Items.Ref        = t.GetModelName();
                        }
                        else
                        {
                            prop.Items.TypeFormat = st;
                        }
                    }
                }

                if (prop.Required)
                {
                    if (schema.Required == null)
                    {
                        schema.Required = new List <string>();
                    }

                    schema.Required.Add(prop.Title);
                }
                schema.Properties.Add(prop);
            }
        }
Esempio n. 2
0
        private Schema BuildSchema(Type type, IList <Type> definitionsTypesList)
        {
            if (type == typeof(void))
            {
                return(null);
            }

            if (type.BaseType == typeof(System.Threading.Tasks.Task))
            {
                type = GetTaskInnerType(type);
            }

            TypeFormat typeFormat = Helpers.MapSwaggerType(type, definitionsTypesList);

            switch (typeFormat.Type)
            {
            case ParameterType.Object:
                return(new Schema
                {
                    Ref = typeFormat.Format
                });

            case ParameterType.Array:
                Type t = type.GetElementType() ?? GetEnumerableType(type);
                if (t == null)
                {
                    return(null);
                }
                definitionsTypesList.Add(t);
                return(new Schema
                {
                    TypeFormat = typeFormat,
                    Ref = HttpUtility.HtmlEncode(t.FullName)
                });

            default:
                definitionsTypesList.Add(type);
                return(new Schema
                {
                    TypeFormat = typeFormat
                });
            }
        }
Esempio n. 3
0
        private static Definition ConvertTypeToDefinition(Type definitionType, IList <string> hiddenTags,
                                                          Stack <Type> typesStack)
        {
            DefinitionSchema schema = new DefinitionSchema
            {
                Name = definitionType.FullName
            };

            ProcessTypeAttributes(definitionType, schema);

            // process
            schema.TypeFormat = Helpers.MapSwaggerType(definitionType, null);
            if (schema.TypeFormat.Type == ParameterType.String && schema.TypeFormat.Format == "enum")
            {
                schema.Enum = new List <string>();
                List <string> listOfEnumNames = definitionType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    schema.Enum.Add(GetEnumMemberValue(definitionType, enumName));
                }
            }
            else if (schema.TypeFormat.Type == ParameterType.Array)
            {
                Type t = GetEnumerableType(definitionType);

                if (t != null)
                {
                    schema.Ref = t.FullName;
                    typesStack.Push(t);
                }
            }
            else
            {
                ProcessProperties(definitionType, schema, hiddenTags, typesStack);
            }

            return(new Definition
            {
                Schema = schema
            });
        }
        private static DefinitionProperty ProcessField(FieldInfo propertyInfo, IList <string> hiddenTags,
                                                       Stack <Type> typesStack)
        {
            if (propertyInfo.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                propertyInfo.GetCustomAttributes <SwaggerWcfTagAttribute>()
                .Select(t => t.TagName)
                .Any(hiddenTags.Contains))
            {
                return(null);
            }

            TypeFormat typeFormat = Helpers.MapSwaggerType(propertyInfo.FieldType, null);

            DefinitionProperty prop = new DefinitionProperty {
                Title = propertyInfo.Name
            };

            DataMemberAttribute dataMemberAttribute = propertyInfo.GetCustomAttribute <DataMemberAttribute>();

            if (dataMemberAttribute != null)
            {
                if (!string.IsNullOrEmpty(dataMemberAttribute.Name))
                {
                    prop.Title = dataMemberAttribute.Name;
                }

                prop.Required = dataMemberAttribute.IsRequired;
            }

            // Special case - if it came out required, but we unwrapped a null-able type,
            // then it's necessarily not required.  Ideally this would only set the default,
            // but we can't tell the difference between an explicit declaration of
            // IsRequired =false on the DataMember attribute and no declaration at all.
            if (prop.Required && propertyInfo.FieldType.IsGenericType &&
                propertyInfo.FieldType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                prop.Required = false;
            }

            DescriptionAttribute descriptionAttribute = propertyInfo.GetCustomAttribute <DescriptionAttribute>();

            if (descriptionAttribute != null)
            {
                prop.Description = descriptionAttribute.Description;
            }

            SwaggerWcfRegexAttribute regexAttr = propertyInfo.GetCustomAttribute <SwaggerWcfRegexAttribute>();

            if (regexAttr != null)
            {
                prop.Pattern = regexAttr.Regex;
            }

            prop.TypeFormat = typeFormat;

            if (prop.TypeFormat.Type == ParameterType.Object)
            {
                typesStack.Push(propertyInfo.FieldType);

                prop.Ref = propertyInfo.FieldType.GetModelName();

                return(prop);
            }

            if (prop.TypeFormat.Type == ParameterType.Array)
            {
                Type subType = DefinitionsBuilder.GetEnumerableType(propertyInfo.FieldType);
                if (subType != null)
                {
                    TypeFormat subTypeFormat = Helpers.MapSwaggerType(subType, null);

                    if (subTypeFormat.Type == ParameterType.Object)
                    {
                        typesStack.Push(subType);
                    }

                    prop.Items = new ParameterItems
                    {
                        TypeFormat = subTypeFormat
                    };
                }
            }

            if ((prop.TypeFormat.Type == ParameterType.Integer && prop.TypeFormat.Format == "enum") || (prop.TypeFormat.Type == ParameterType.Array && prop.Items.TypeFormat.Format == "enum"))
            {
                prop.Enum = new List <int>();

                Type propType = propertyInfo.FieldType;

                if (propType.IsGenericType && (propType.GetGenericTypeDefinition() == typeof(Nullable <>) || propType.GetGenericTypeDefinition() == typeof(List <>)))
                {
                    propType = propType.GetEnumerableType();
                }

                string        enumDescription = "";
                List <string> listOfEnumNames = propType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    var    enumMemberItem        = Enum.Parse(propType, enumName, true);
                    string enumMemberDescription = DefinitionsBuilder.GetEnumDescription((Enum)enumMemberItem);
                    enumMemberDescription = (string.IsNullOrWhiteSpace(enumMemberDescription)) ? "" : $"({enumMemberDescription})";
                    int enumMemberValue = DefinitionsBuilder.GetEnumMemberValue(propType, enumName);
                    if (prop.Description != null)
                    {
                        prop.Enum.Add(enumMemberValue);
                    }
                    enumDescription += $"    {enumName}{System.Web.HttpUtility.HtmlEncode(" = ")}{enumMemberValue} {enumMemberDescription}\r\n";
                }

                if (enumDescription != "")
                {
                    prop.Description += $"\r\n\r\n{enumDescription}";
                }
            }

            // Apply any options set in a [SwaggerWcfProperty]
            DefinitionsBuilder.ApplyAttributeOptions(propertyInfo, prop);

            return(prop);
        }
Esempio n. 5
0
        private Schema BuildSchema(Type type, MethodInfo implementation, MethodInfo declaration, bool wrappedResponse, IList <Type> definitionsTypesList)
        {
            if (type == typeof(void) || type == typeof(Task))
            {
                return(null);
            }

            if (type.BaseType == typeof(Task))
            {
                type = GetTaskInnerType(type);
            }

            TypeFormat typeFormat;

            if (wrappedResponse)
            {
                string funcName = implementation.Name;

                string typeName = implementation.GetCustomAttribute <SwaggerWcfReturnTypeAttribute>()?.Name
                                  ?? declaration.GetCustomAttribute <SwaggerWcfReturnTypeAttribute>()?.Name
                                  ?? funcName + "Result";

                TypeBuilder typeBuilder = new TypeBuilder(typeName + "Wrapper");

                typeBuilder.AddField(typeName, type, true);

                typeFormat = Helpers.MapSwaggerType(typeBuilder.Type, definitionsTypesList);
            }
            else
            {
                typeFormat = Helpers.MapSwaggerType(type, definitionsTypesList);
            }

            switch (typeFormat.Type)
            {
            case ParameterType.Object:
                return(new Schema
                {
                    Ref = typeFormat.Format
                });

            case ParameterType.Array:
                Type t = type.GetElementType() ?? GetEnumerableType(type);
                if (t == null)
                {
                    return(null);
                }

                TypeFormat arrayTypeFormat = Helpers.MapSwaggerType(t);
                if (arrayTypeFormat.IsPrimitiveType)
                {
                    return(new Schema
                    {
                        TypeFormat = typeFormat,
                        ArrayTypeFormat = arrayTypeFormat
                    });
                }
                else
                {
                    definitionsTypesList.Add(t);
                    return(new Schema
                    {
                        TypeFormat = typeFormat,
                        Ref = HttpUtility.HtmlEncode(t.GetModelName())
                    });
                }

            default:
                definitionsTypesList.Add(type);
                return(new Schema
                {
                    TypeFormat = typeFormat
                });
            }
        }
Esempio n. 6
0
        private ParameterBase GetParameter(TypeFormat typeFormat,
                                           MethodInfo declaration,
                                           MethodInfo implementation,
                                           ParameterInfo parameter,
                                           SwaggerWcfParameterAttribute settings,
                                           string uriTemplate,
                                           bool wrappedRequest,
                                           IList <Type> definitionsTypesList,
                                           InType inType)
        {
            string description = settings?.Description;
            bool   required    = settings != null && settings.Required;
            string name        = inType == InType.Query ? ResolveParameterNameFromUri(uriTemplate, parameter) : parameter.Name;

            if (inType == InType.Path)
            {
                required = true;
            }

            if (!required && !parameter.HasDefaultValue)
            {
                required = true;
            }

            Type paramType = settings == null || settings.ParameterType == null
                ? parameter.ParameterType
                : settings.ParameterType;

            if (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                required  = false;
                paramType = paramType.GenericTypeArguments[0];
            }

            if (typeFormat.Type == ParameterType.Object)
            {
                return(new ParameterSchema
                {
                    Name = name,
                    Description = description,
                    In = inType,
                    Required = required,
                    SchemaRef = typeFormat.Format
                });
            }

            if (inType == InType.Body)
            {
                if (typeFormat.Type == ParameterType.Array)
                {
                    Type       t             = paramType.GetElementType() ?? GetEnumerableType(paramType);
                    TypeFormat subTypeFormat = Helpers.MapSwaggerType(t);

                    ParameterItems items;

                    if (subTypeFormat.IsPrimitiveType || subTypeFormat.IsEnum)
                    {
                        items = new ParameterItems
                        {
                            TypeFormat = subTypeFormat
                        };
                    }
                    else
                    {
                        items = new ParameterItems
                        {
                            Items = new ParameterSchema
                            {
                                SchemaRef = t.GetModelName()
                            }
                        };
                    }

                    ParameterPrimitive arrayParam = new ParameterPrimitive
                    {
                        Name             = name,
                        Description      = description,
                        In               = inType,
                        Required         = required,
                        TypeFormat       = typeFormat,
                        Items            = items,
                        CollectionFormat = CollectionFormat.Csv
                    };

                    //it's a complex type, so we'll need to map it later
                    if (definitionsTypesList != null && !definitionsTypesList.Contains(t))
                    {
                        definitionsTypesList.Add(t);
                    }

                    return(arrayParam);
                }
                if (typeFormat.IsPrimitiveType || typeFormat.IsEnum)
                {
                    bool isGetRequest = implementation.GetCustomAttributes <WebGetAttribute>().Any() ||
                                        declaration.GetCustomAttributes <WebGetAttribute>().Any();
                    if (!isGetRequest)
                    {
                        WebInvokeAttribute webInvoke = implementation.GetCustomAttribute <WebInvokeAttribute>()
                                                       ?? declaration.GetCustomAttribute <WebInvokeAttribute>();
                        if (webInvoke != null && webInvoke.Method == "GET")
                        {
                            isGetRequest = true;
                        }
                    }
                    if (!wrappedRequest && isGetRequest)
                    {
                        ParameterPrimitive paramPrimitive = new ParameterPrimitive
                        {
                            Name        = name,
                            Description = description,
                            In          = InType.Query,
                            Required    = required,
                            TypeFormat  = typeFormat
                        };
                        return(paramPrimitive);
                    }
                    else
                    {
                        ParameterPrimitive paramPrimitive = new ParameterPrimitive
                        {
                            Name        = name,
                            Description = description,
                            In          = inType,
                            Required    = required,
                            TypeFormat  = typeFormat
                        };
                        return(paramPrimitive);
                    }
                }

                //it's a complex type, so we'll need to map it later
                if (definitionsTypesList != null && !definitionsTypesList.Contains(paramType))
                {
                    definitionsTypesList.Add(paramType);
                }

                typeFormat = new TypeFormat(ParameterType.Object,
                                            HttpUtility.HtmlEncode(paramType.GetModelName()));

                return(new ParameterSchema
                {
                    Name = name,
                    Description = description,
                    In = inType,
                    Required = required,
                    SchemaRef = typeFormat.Format
                });
            }

            ParameterPrimitive param = new ParameterPrimitive
            {
                Name        = name,
                Description = description,
                In          = inType,
                Required    = required,
                TypeFormat  = typeFormat
            };

            return(param);
        }
Esempio n. 7
0
        internal IEnumerable <Tuple <string, PathAction> > GetActions(MethodInfo[] targetMethods,
                                                                      MethodInfo[] interfaceMethods,
                                                                      IList <Type> definitionsTypesList)
        {
            int methodsCounts = interfaceMethods.Length;

            for (int index = 0; index < methodsCounts; index++)
            {
                MethodInfo implementation = targetMethods[index];
                MethodInfo declaration    = interfaceMethods[index];

                //if a tag from either implementation or declaration is marked as not visible, skip it
                List <SwaggerWcfTagAttribute> methodTags =
                    implementation.GetCustomAttributes <SwaggerWcfTagAttribute>().ToList();
                methodTags =
                    methodTags.Concat(declaration.GetCustomAttributes <SwaggerWcfTagAttribute>()).ToList();

                methodTags = methodTags.Distinct().ToList();

                // If no tags on the method - check declared Type/Interface itself
                if (methodTags.Count < 1)
                {
                    methodTags = implementation.DeclaringType.GetCustomAttributes <SwaggerWcfTagAttribute>()
                                 .Concat(declaration.DeclaringType.GetCustomAttributes <SwaggerWcfTagAttribute>())
                                 .ToList();
                }

                if ((methodTags.Count == 0 && HiddenTags.Contains("default")) ||
                    methodTags.Any(t => HiddenTags.Contains(t.TagName)))
                {
                    continue;
                }

                //if the method is marked Hidden anywhere, skip it (even if methods tags listed as visible).
                if ((implementation.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                     declaration.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null)
                    )
                {
                    continue;
                }

                //find the WebGet/Invoke attributes, or skip if neither is present
                WebGetAttribute    wg = declaration.GetCustomAttribute <WebGetAttribute>();
                WebInvokeAttribute wi = declaration.GetCustomAttribute <WebInvokeAttribute>();
                if (wg == null && wi == null)
                {
                    continue;
                }

                string httpMethod  = (wi == null) ? "GET" : wi.Method ?? "POST";
                string uriTemplate = GetUriTemplate(wi, wg, declaration);

                bool wrappedRequest  = IsRequestWrapped(wg, wi);
                bool wrappedResponse = IsResponseWrapped(wg, wi);

                var wcfPathAttribute = (implementation.GetCustomAttribute(typeof(SwaggerWcfPathAttribute), false) as SwaggerWcfPathAttribute)
                                       ?? (declaration.GetCustomAttribute(typeof(SwaggerWcfPathAttribute), false) as SwaggerWcfPathAttribute);
                int sortOrder = (wcfPathAttribute?.SortOrder).GetValueOrDefault();


                //implementation description overrides interface description
                string description =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "Description") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "Description") ??
                    Helpers.GetCustomAttributeValue <string, DescriptionAttribute>(implementation, "Description") ??
                    Helpers.GetCustomAttributeValue <string, DescriptionAttribute>(declaration, "Description") ??
                    "";

                string summary =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "Summary") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "Summary") ??
                    "";

                string operationId =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "OperationId") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "OperationId") ??
                    "";
                if (operationId == "")
                {
                    if (implementation.DeclaringType != null)
                    {
                        operationId = implementation.DeclaringType.FullName + ".";
                    }
                    operationId += implementation.Name;
                }

                string externalDocsDescription =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation,
                                                                                      "ExternalDocsDescription") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration,
                                                                                      "ExternalDocsDescription") ??
                    "";

                string externalDocsUrl =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "ExternalDocsUrl") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "ExternalDocsUrl") ??
                    "";

                ExternalDocumentation externalDocs = null;
                if (!string.IsNullOrWhiteSpace(externalDocsDescription) || !string.IsNullOrWhiteSpace(externalDocsUrl))
                {
                    externalDocs = new ExternalDocumentation
                    {
                        Description = externalDocsDescription,
                        Url         = HttpUtility.HtmlEncode(externalDocsUrl)
                    };
                }

                bool deprecated =
                    Helpers.GetCustomAttributeValue <SwaggerWcfPathAttribute>(implementation, "Deprecated");
                if (!deprecated)
                {
                    deprecated = Helpers.GetCustomAttributeValue <SwaggerWcfPathAttribute>(declaration, "Deprecated");
                }

                string operationPath =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "OperationPath") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "OperationPath");
                if (!string.IsNullOrWhiteSpace(operationPath))
                {
                    uriTemplate = ConcatPaths(operationPath, uriTemplate);
                }

                PathAction operation = new PathAction
                {
                    Id          = httpMethod.ToLowerInvariant(),
                    SortOrder   = sortOrder,
                    Summary     = summary,
                    Description = description,
                    Tags        =
                        methodTags.Where(t => !t.HideFromSpec).Select(t => HttpUtility.HtmlEncode(t.TagName)).ToList(),
                    Consumes     = new List <string>(GetConsumes(implementation, declaration)),
                    Produces     = new List <string>(GetProduces(implementation, declaration)),
                    Deprecated   = deprecated,
                    OperationId  = HttpUtility.HtmlEncode(operationId),
                    ExternalDocs = externalDocs,
                    Responses    = GetResponseCodes(implementation, declaration, wrappedResponse, definitionsTypesList),
                    Security     = GetMethodSecurity(implementation, declaration)
                                   // Schemes = TODO: how to get available schemes for this WCF service? (schemes: http/https)
                };

                //try to map each implementation parameter to the uriTemplate.
                ParameterInfo[] parameters = declaration.GetParameters();
                if (parameters.Any())
                {
                    operation.Parameters = new List <ParameterBase>();
                }

                List <SwaggerWcfHeaderAttribute> headers =
                    implementation.GetCustomAttributes <SwaggerWcfHeaderAttribute>().ToList();
                headers = headers.Concat(declaration.GetCustomAttributes <SwaggerWcfHeaderAttribute>()).ToList();

                // remove duplicates
                headers = headers.GroupBy(h => h.Name).Select(g => g.First()).ToList();

                // parameters - headers
                foreach (SwaggerWcfHeaderAttribute attr in headers)
                {
                    operation.Parameters.Add(new ParameterPrimitive
                    {
                        Name        = attr.Name,
                        Description = attr.Description,
                        Default     = attr.DefaultValue,
                        In          = InType.Header,
                        Required    = attr.Required,
                        TypeFormat  = new TypeFormat(ParameterType.String, null)
                    });
                }

                bool        isGetRequest       = httpMethod == "GET";
                int         bodyParameterCount = parameters.Where(p => GetInType(uriTemplate, p.Name) == InType.Body).Count();
                TypeBuilder typeBuilder        = null;
                if (!wrappedRequest && !isGetRequest && bodyParameterCount > 1)
                {
                    wrappedRequest = true;
                }
                if (wrappedRequest)
                {
                    typeBuilder = new TypeBuilder(implementation.GetWrappedName(declaration));
                }

                var declarationName = declaration.Name;
                foreach (ParameterInfo parameter in parameters)
                {
                    SwaggerWcfParameterAttribute settings =
                        implementation.GetParameters()
                        .First(p => p.Position.Equals(parameter.Position))
                        .GetCustomAttribute <SwaggerWcfParameterAttribute>() ??
                        parameter.GetCustomAttribute <SwaggerWcfParameterAttribute>();

                    if (implementation.GetParameters()
                        .First(p => p.Position.Equals(parameter.Position))
                        .GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                        parameter.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null)
                    {
                        continue;
                    }

                    List <SwaggerWcfTagAttribute> piTags =
                        methodTags.Concat(parameter.GetCustomAttributes <SwaggerWcfTagAttribute>())
                        .ToList();

                    InType inType = GetInType(uriTemplate, parameter.Name);

                    if (inType == InType.Body && wrappedRequest)
                    {
                        bool required = settings != null && settings.Required;

                        if (!required && !parameter.HasDefaultValue)
                        {
                            required = true;
                        }

                        typeBuilder.AddField(parameter.Name, parameter.ParameterType, required);

                        continue;
                    }

                    if (piTags.Any(t => HiddenTags.Contains(t.TagName)))
                    {
                        continue;
                    }

                    Type type = settings == null || settings.ParameterType == null
                        ? parameter.ParameterType
                        : settings.ParameterType;

                    TypeFormat typeFormat = Helpers.MapSwaggerType(type, definitionsTypesList);

                    operation.Parameters.Add(GetParameter(typeFormat, declaration, implementation, parameter, settings, uriTemplate, wrappedRequest,
                                                          definitionsTypesList, inType));
                }

                if (wrappedRequest)
                {
                    TypeFormat typeFormat = Helpers.MapSwaggerType(typeBuilder.Type, definitionsTypesList);

                    operation.Parameters.Add(new ParameterSchema
                    {
                        Name      = implementation.GetWrappedName(declaration) + "Wrapper",
                        In        = InType.Body,
                        Required  = true,
                        SchemaRef = typeFormat.Format
                    });
                }

                if (!string.IsNullOrWhiteSpace(uriTemplate))
                {
                    int indexOfQuestionMark = uriTemplate.IndexOf('?');
                    if (indexOfQuestionMark >= 0)
                    {
                        uriTemplate = uriTemplate.Substring(0, indexOfQuestionMark);
                    }

                    uriTemplate = RemoveParametersDefaultValuesFromUri(uriTemplate);
                }

                yield return(new Tuple <string, PathAction>(uriTemplate, operation));
            }
        }
Esempio n. 8
0
        private static DefinitionProperty ProcessProperty(PropertyInfo propertyInfo, IList <string> hiddenTags,
                                                          Stack <Type> typesStack)
        {
            if (propertyInfo.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                propertyInfo.GetCustomAttributes <SwaggerWcfTagAttribute>()
                .Select(t => t.TagName)
                .Any(hiddenTags.Contains))
            {
                return(null);
            }

            TypeFormat typeFormat = Helpers.MapSwaggerType(propertyInfo.PropertyType, null);

            DefinitionProperty prop = new DefinitionProperty {
                Title = propertyInfo.Name
            };

            DataMemberAttribute dataMemberAttribute = propertyInfo.GetCustomAttribute <DataMemberAttribute>();

            if (dataMemberAttribute != null)
            {
                if (!string.IsNullOrEmpty(dataMemberAttribute.Name))
                {
                    prop.Title = dataMemberAttribute.Name;
                }

                prop.Required = dataMemberAttribute.IsRequired;
            }

            // Special case - if it came out required, but we unwrapped a null-able type,
            // then it's necessarily not required.  Ideally this would only set the default,
            // but we can't tell the difference between an explicit delaration of
            // IsRequired =false on the DataMember attribute and no declaration at all.
            if (prop.Required && propertyInfo.PropertyType.IsGenericType &&
                propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                prop.Required = false;
            }

            DescriptionAttribute descriptionAttribute = propertyInfo.GetCustomAttribute <DescriptionAttribute>();

            if (descriptionAttribute != null)
            {
                prop.Description = descriptionAttribute.Description;
            }

            prop.TypeFormat = typeFormat;

            if (prop.TypeFormat.Type == ParameterType.Object)
            {
                typesStack.Push(propertyInfo.PropertyType);

                prop.Ref = propertyInfo.PropertyType.FullName;

                return(prop);
            }

            if (prop.TypeFormat.Type == ParameterType.Array)
            {
                Type subType = GetEnumerableType(propertyInfo.PropertyType);
                if (subType != null)
                {
                    TypeFormat subTypeFormat = Helpers.MapSwaggerType(subType, null);

                    if (subTypeFormat.Type == ParameterType.Object)
                    {
                        typesStack.Push(subType);
                    }

                    prop.Items = new ParameterItems
                    {
                        TypeFormat = subTypeFormat
                    };
                }
            }

            if (prop.TypeFormat.Type == ParameterType.String && prop.TypeFormat.Format == "enum")
            {
                prop.Enum = new List <string>();

                Type propType = propertyInfo.PropertyType;

                if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    propType = propType.GetEnumerableType();
                }

                List <string> listOfEnumNames = propType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    prop.Enum.Add(GetEnumMemberValue(propType, enumName));
                }
            }

            // Apply any options set in a [SwaggerWcfProperty]
            ApplyAttributeOptions(propertyInfo, prop);

            return(prop);
        }
Esempio n. 9
0
        private static Definition ConvertTypeToDefinition(Type definitionType, IList <string> hiddenTags,
                                                          Stack <Type> typesStack)
        {
            DefinitionSchema schema = new DefinitionSchema();

            //Get DataContractAttribute to set Schema name to match TypeFormat
            DataContractAttribute dca = definitionType.GetCustomAttribute <DataContractAttribute>();

            //If DataContractAttribute.Name is set use that, otherwise use definitionType.Name
            if (dca != null)
            {
                if (!String.IsNullOrWhiteSpace(dca.Name))
                {
                    schema.Name = dca.Name;
                }
                else
                {
                    schema.Name = definitionType.Name;
                }
            }

            ProcessTypeAttributes(definitionType, schema);

            // process
            schema.TypeFormat = Helpers.MapSwaggerType(definitionType, null);

            if (schema.TypeFormat.IsPrimitiveType)
            {
                return(null);
            }

            if (schema.TypeFormat.Type == ParameterType.String && schema.TypeFormat.Format == "enum")
            {
                schema.Enum = new List <string>();

                Type propType = definitionType;

                if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    propType = propType.GetEnumerableType();
                }

                List <string> listOfEnumNames = propType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    schema.Enum.Add(GetEnumMemberValue(propType, enumName));
                }
            }
            else if (schema.TypeFormat.Type == ParameterType.Array)
            {
                Type t = GetEnumerableType(definitionType);

                if (t != null)
                {
                    schema.Ref = t.FullName;
                    typesStack.Push(t);
                }
            }
            else
            {
                ProcessProperties(definitionType, schema, hiddenTags, typesStack);
            }

            return(new Definition
            {
                Schema = schema
            });
        }
Esempio n. 10
0
        private static DefinitionProperty ProcessProperty(PropertyInfo propertyInfo, IList <string> hiddenTags,
                                                          Stack <Type> typesStack)
        {
            if (propertyInfo.GetCustomAttribute <DataMemberAttribute>() == null ||
                propertyInfo.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                propertyInfo.GetCustomAttributes <SwaggerWcfTagAttribute>()
                .Select(t => t.TagName)
                .Any(hiddenTags.Contains))
            {
                return(null);
            }

            TypeFormat typeFormat = Helpers.MapSwaggerType(propertyInfo.PropertyType, null);

            DefinitionProperty prop = new DefinitionProperty {
                Title = propertyInfo.Name
            };

            DataMemberAttribute dataMemberAttribute = propertyInfo.GetCustomAttribute <DataMemberAttribute>();

            if (dataMemberAttribute != null)
            {
                if (!string.IsNullOrEmpty(dataMemberAttribute.Name))
                {
                    prop.Title = dataMemberAttribute.Name;
                }

                prop.Required = dataMemberAttribute.IsRequired;
            }

            DescriptionAttribute descriptionAttribute = propertyInfo.GetCustomAttribute <DescriptionAttribute>();

            if (descriptionAttribute != null)
            {
                prop.Description = descriptionAttribute.Description;
            }

            prop.TypeFormat = typeFormat;

            if (prop.TypeFormat.Type == ParameterType.Object)
            {
                typesStack.Push(propertyInfo.PropertyType);

                prop.Ref = propertyInfo.PropertyType.FullName;

                return(prop);
            }

            if (prop.TypeFormat.Type == ParameterType.Array)
            {
                Type subType = propertyInfo.PropertyType.GetEnumerableType();
                if (subType != null)
                {
                    TypeFormat subTypeFormat = Helpers.MapSwaggerType(subType, null);

                    if (subTypeFormat.Type == ParameterType.Object)
                    {
                        typesStack.Push(subType);
                    }

                    prop.Items = new ParameterItems
                    {
                        TypeFormat = subTypeFormat
                    };
                }
            }

            if (prop.TypeFormat.Type == ParameterType.String && prop.TypeFormat.Format == "enum")
            {
                prop.Enum = new List <string>();
                List <string> listOfEnumNames = propertyInfo.PropertyType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    prop.Enum.Add(GetEnumMemberValue(propertyInfo.PropertyType, enumName));
                }
            }

            return(prop);
        }
        private static void ProcessProperties(Type definitionType, DefinitionSchema schema, IList <string> hiddenTags,
                                              Stack <Type> typesStack)
        {
            List <PropertyInfo> properties = new List <PropertyInfo>();
            var type = definitionType;

            while (type != null)
            {
                var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                foreach (var prop in props)
                {
                    if (properties.Any(p => p.Name == prop.Name))
                    {
                        continue;
                    }

                    properties.Add(prop);
                }

                type = type.BaseType;
            }


            //PropertyInfo[] properties = definitionType.GetProperties(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic);
            schema.Properties = new List <DefinitionProperty>();

            foreach (PropertyInfo propertyInfo in properties)
            {
                DefinitionProperty prop = ProcessProperty(propertyInfo, hiddenTags, typesStack);

                if (prop == null)
                {
                    continue;
                }

                if (prop.TypeFormat.Type == ParameterType.Array)
                {
                    Type propType = propertyInfo.PropertyType;

                    Type t = propType.GetElementType() ?? GetEnumerableType(propType);

                    if (t != null)
                    {
                        //prop.TypeFormat = new TypeFormat(prop.TypeFormat.Type, HttpUtility.HtmlEncode(t.FullName));
                        prop.TypeFormat = new TypeFormat(prop.TypeFormat.Type, null);

                        TypeFormat st = Helpers.MapSwaggerType(t);
                        if (st.Type == ParameterType.Array || st.Type == ParameterType.Object)
                        {
                            prop.Items.TypeFormat = new TypeFormat(ParameterType.Unknown, null);
                            prop.Items.Ref        = t.FullName;
                        }
                        else
                        {
                            prop.Items.TypeFormat = st;
                        }
                    }
                }

                if (prop.Required)
                {
                    if (schema.Required == null)
                    {
                        schema.Required = new List <string>();
                    }

                    schema.Required.Add(prop.Title);
                }
                schema.Properties.Add(prop);
            }
        }
Esempio n. 12
0
        internal IEnumerable <Tuple <string, PathAction> > GetActions(MethodInfo[] targetMethods,
                                                                      MethodInfo[] interfaceMethods,
                                                                      IList <Type> definitionsTypesList)
        {
            int methodsCounts = interfaceMethods.Count();

            for (int index = 0; index < methodsCounts; index++)
            {
                MethodInfo implementation = targetMethods[index];
                MethodInfo declaration    = interfaceMethods[index];

                //if the method is marked Hidden anywhere, skip it
                if (implementation.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                    declaration.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null)
                {
                    continue;
                }

                //if a tag from either implementation or declaration is marked as not visible, skip it
                List <SwaggerWcfTagAttribute> methodTags =
                    implementation.GetCustomAttributes <SwaggerWcfTagAttribute>().ToList();
                methodTags =
                    methodTags.Concat(declaration.GetCustomAttributes <SwaggerWcfTagAttribute>()).ToList();
                methodTags = methodTags.Distinct().ToList();

                if (methodTags.Select(t => t.TagName).Any(HiddenTags.Contains))
                {
                    continue;
                }

                //find the WebGet/Invoke attributes, or skip if neither is present
                WebGetAttribute    wg = declaration.GetCustomAttribute <WebGetAttribute>();
                WebInvokeAttribute wi = declaration.GetCustomAttribute <WebInvokeAttribute>();
                if (wg == null && wi == null)
                {
                    continue;
                }

                string httpMethod  = (wi == null) ? "GET" : wi.Method ?? "POST";
                string uriTemplate = (wi == null) ? (wg.UriTemplate ?? "") : (wi.UriTemplate ?? "");

                //implementation description overrides interface description
                string description =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "Description") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "Description") ??
                    Helpers.GetCustomAttributeValue <string, DescriptionAttribute>(implementation, "Description") ??
                    Helpers.GetCustomAttributeValue <string, DescriptionAttribute>(declaration, "Description") ??
                    "";

                string summary =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "Summary") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "Summary") ??
                    "";

                string operationId =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "OperationId") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "OperationId") ??
                    "";
                if (operationId == "")
                {
                    if (implementation.DeclaringType != null)
                    {
                        operationId = implementation.DeclaringType.FullName + ".";
                    }
                    operationId += implementation.Name;
                }

                string externalDocsDescription =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation,
                                                                                      "ExternalDocsDescription") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration,
                                                                                      "ExternalDocsDescription") ??
                    "";

                string externalDocsUrl =
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(implementation, "ExternalDocsUrl") ??
                    Helpers.GetCustomAttributeValue <string, SwaggerWcfPathAttribute>(declaration, "ExternalDocsUrl") ??
                    "";

                ExternalDocumentation externalDocs = null;
                if (!string.IsNullOrWhiteSpace(externalDocsDescription) || !string.IsNullOrWhiteSpace(externalDocsUrl))
                {
                    externalDocs = new ExternalDocumentation
                    {
                        Description = HttpUtility.HtmlEncode(externalDocsDescription),
                        Url         = HttpUtility.HtmlEncode(externalDocsUrl)
                    };
                }

                bool deprecated =
                    Helpers.GetCustomAttributeValue <SwaggerWcfPathAttribute>(implementation, "Deprecated");
                if (!deprecated)
                {
                    deprecated = Helpers.GetCustomAttributeValue <SwaggerWcfPathAttribute>(declaration, "Deprecated");
                }

                PathAction operation = new PathAction
                {
                    Id          = httpMethod.ToLowerInvariant(),
                    Summary     = HttpUtility.HtmlEncode(summary),
                    Description = HttpUtility.HtmlEncode(description),
                    Tags        =
                        methodTags.Where(t => !t.HideFromSpec).Select(t => HttpUtility.HtmlEncode(t.TagName)).ToList(),
                    Consumes     = new List <string>(GetConsumes(implementation, declaration)),
                    Produces     = new List <string>(GetProduces(implementation, declaration)),
                    Deprecated   = deprecated,
                    OperationId  = HttpUtility.HtmlEncode(operationId),
                    ExternalDocs = externalDocs,
                    Responses    = GetResponseCodes(implementation, declaration, definitionsTypesList)
                                   // Schemes = TODO: how to get available schemes for this WCF service? (schemes: http/https)
                };

                //try to map each implementation parameter to the uriTemplate.
                ParameterInfo[] parameters = declaration.GetParameters();
                if (parameters.Any())
                {
                    operation.Parameters = new List <ParameterBase>();
                }
                foreach (ParameterInfo parameter in parameters)
                {
                    TypeFormat typeFormat = Helpers.MapSwaggerType(parameter.ParameterType, definitionsTypesList);

                    SwaggerWcfParameterAttribute settings =
                        implementation.GetParameters()
                        .First(p => p.Position.Equals(parameter.Position))
                        .GetCustomAttribute <SwaggerWcfParameterAttribute>() ??
                        parameter.GetCustomAttribute <SwaggerWcfParameterAttribute>();

                    if (implementation.GetParameters()
                        .First(p => p.Position.Equals(parameter.Position))
                        .GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null ||
                        parameter.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null)
                    {
                        continue;
                    }

                    List <SwaggerWcfTagAttribute> piTags =
                        methodTags.Concat(parameter.GetCustomAttributes <SwaggerWcfTagAttribute>())
                        .ToList();

                    if (piTags.Select(t => t.TagName).Any(HiddenTags.Contains))
                    {
                        continue;
                    }

                    operation.Parameters.Add(GetParameter(typeFormat, parameter, settings, uriTemplate,
                                                          definitionsTypesList));
                }

                if (!string.IsNullOrWhiteSpace(uriTemplate))
                {
                    int indexOfQuestionMark = uriTemplate.IndexOf('?');
                    if (indexOfQuestionMark >= 0)
                    {
                        uriTemplate = uriTemplate.Substring(0, indexOfQuestionMark);
                    }
                }
                yield return(new Tuple <string, PathAction>(uriTemplate, operation));
            }
        }
Esempio n. 13
0
        private static Definition ConvertTypeToDefinition(Type definitionType, IList <string> hiddenTags,
                                                          Stack <Type> typesStack)
        {
            DefinitionSchema schema = new DefinitionSchema
            {
                Name = definitionType.GetModelName()
            };

            ProcessTypeAttributes(definitionType, schema);

            // process
            schema.TypeFormat = Helpers.MapSwaggerType(definitionType, null);

            if (schema.TypeFormat.IsPrimitiveType)
            {
                return(null);
            }

            if (schema.TypeFormat.Type == ParameterType.Integer && schema.TypeFormat.Format == "enum")
            {
                schema.Enum = new List <int>();

                Type propType = definitionType;

                if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    propType = propType.GetEnumerableType();
                }

                string        enumDescription = "";
                List <string> listOfEnumNames = propType.GetEnumNames().ToList();
                foreach (string enumName in listOfEnumNames)
                {
                    var enumMemberValue = DefinitionsBuilder.GetEnumMemberValue(propType, enumName);
                    var enumMemberItem  = Enum.Parse(propType, enumName, true);

                    string enumMemberDescription = DefinitionsBuilder.GetEnumDescription((Enum)enumMemberItem);
                    enumMemberDescription = (string.IsNullOrWhiteSpace(enumMemberDescription)) ? "" : $"({enumMemberDescription})";

                    if (schema.Description != null)
                    {
                        enumDescription += $"{Environment.NewLine}* `{enumMemberValue}` - {enumName} {enumMemberDescription}";
                        schema.Enum.Add(enumMemberValue);
                    }
                }

                if (schema.Description != null && enumDescription != "")
                {
                    schema.Description += $":{Environment.NewLine}{enumDescription}";
                }
            }
            else if (schema.TypeFormat.Type == ParameterType.Array)
            {
                Type t = GetEnumerableType(definitionType);

                if (t != null)
                {
                    schema.Ref = definitionType.GetModelName();
                    typesStack.Push(t);
                }
            }
            else
            {
                schema.Properties = new List <DefinitionProperty>();
                TypePropertiesProcessor.ProcessProperties(definitionType, schema, hiddenTags, typesStack);
                TypeFieldsProcessor.ProcessFields(definitionType, schema, hiddenTags, typesStack);
            }

            return(new Definition
            {
                Schema = schema
            });
        }