Beispiel #1
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));
            }
        }
Beispiel #2
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));
            }
        }