Exemple #1
0
        public static IApplicationBuilder UseSwagger(this IApplicationBuilder builder, Action <SwaggerConfig> configAction = null)
        {
            builder.ApplicationServices.GetRequiredService <IProtocolProcessor>();

            var           swagger = builder.ApplicationServices.GetRequiredService <ISwaggerApiInfoProvider>();
            SwaggerConfig config  = new SwaggerConfig();

            configAction?.Invoke(config);

            swagger.ScanApiInfo(config);

            builder.UseMiddleware <SwaggerMiddleware>(config.RoutePath);

            return(builder);
        }
        private void ProcessPaths(Dictionary <string, Dictionary <string, SwaggerMethod> > swaggerPaths,
                                  List <SwaggerTag> tags, HttpRouteOptions routeOptions, Dictionary <string, SwaggerDefinition> definitions, SwaggerConfig config)
        {
            routeOptions.Items.ForEach(item =>
            {
                var path = CreateSwaggerMethod(item.AcceptVerb);

                var tagName = item.InvokeMethod.DeclaringType.Name.Substring(1);

                if (!tags.Exists(x => x.Name == tagName))
                {
                    tags.Add(new SwaggerTag
                    {
                        Name        = item.InvokeMethod.DeclaringType.Name.Substring(1),
                        Description = this._resolver.GetTypeComment(item.InvokeMethod.DeclaringType)
                    });
                }


                path.Tags = new List <string> {
                    //item.Category??"default",
                    //this._resolver.GetTypeComment(item.InvokeMethod.DeclaringType)
                    tagName
                };

                path.Summary = GetSummary(item);

                string verb;
                //path.Summary = item.AcceptVerb.ToString();
                if (item.AcceptVerb == RestfulVerb.Any || item.AcceptVerb == RestfulVerb.Get ||
                    item.AcceptVerb == RestfulVerb.UnKnown)
                {
                    //path.Consumes = new List<string> {"application/json"};
                    verb = "get";
                }
                else if (item.AcceptVerb == RestfulVerb.Put || item.AcceptVerb == RestfulVerb.Post ||
                         item.AcceptVerb == RestfulVerb.Patch ||
                         item.AcceptVerb == RestfulVerb.Delete)
                {
                    path.Consumes = new List <string> {
                        "application/x-www-form-urlencoded", "application/json"
                    };
                    verb = item.AcceptVerb.ToString().ToLower();
                }
                else
                {
                    //path.Consumes = new List<string> {"application/x-www-form-urlencoded","application/json"};
                    verb = item.AcceptVerb.ToString().ToLower();
                }

                string invokeName = item.InvokeMethod.Name.EndsWith("Async")?
                                    item.InvokeMethod.Name.Substring(0, item.InvokeMethod.Name.Length - 5):
                                    item.InvokeMethod.Name;
                path.OperationId = invokeName;

                path.Description = this._resolver.GetMethodComment(item.InvokeMethod);

                path.Parameters = new List <SwaggerApiParameters>();

                ProcessParameters(item.AcceptVerb, path.Parameters, item.InvokeMethod.GetParameters(), definitions, config);

                path.Responses = new Dictionary <string, SwaggerApiResponse>();

                ProcessResponses(path.Responses, item.InvokeMethod.ReturnParameter, definitions, config);

                swaggerPaths.Add(item.Path, new Dictionary <string, SwaggerMethod> {
                    { verb, path }
                });
            });
        }
        private SwaggerItemSchema GetSwaggerItemSchema(Type type, Dictionary <string, SwaggerDefinition> definitions, SwaggerConfig config)
        {
            if (type.IsArray && type.HasElementType)
            {
                SwaggerArrayItemSchema arrayItem = new SwaggerArrayItemSchema();
                arrayItem.Items.Add(new SwaggerSingleItemSchema
                {
                    Ref = "#/definitions/" + type.GetElementType().Name
                });
                CreateSwaggerDefinition(type.GetElementType().Name, type.GetElementType(), definitions, config);
                return(arrayItem);
            }

            SwaggerSingleItemSchema singleItem = new SwaggerSingleItemSchema {
                Ref = "#/definitions/" + type.Name
            };

            CreateSwaggerDefinition(type.Name, type, definitions, config);

            return(singleItem);
        }
        private void ProcessParameters(RestfulVerb verb, List <SwaggerApiParameters> pathParameters, ParameterInfo[] getParameters
                                       , Dictionary <string, SwaggerDefinition> definitions, SwaggerConfig config)
        {
            var parameter  = getParameters[0];
            var properties = parameter.ParameterType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

            properties.ForEach(p =>
            {
                if (config.IngoreFields.Contains(p.Name))
                {
                    return;
                }

                SwaggerApiParameters apiParameter = new SwaggerApiParameters
                {
                    Name        = p.Name.ToCamelCase(),
                    Description = this._resolver.GetMemberInfoComment(p)
                };

                if (p.PropertyType == typeof(string) || p.PropertyType.IsValueType)
                {
                    apiParameter.Type = GetSwaggerType(p.PropertyType);
                    apiParameter.In   = verb == RestfulVerb.Any || verb == RestfulVerb.Get ? "query" : "formData";
                }
                else
                {
                    apiParameter.In     = verb == RestfulVerb.Any || verb == RestfulVerb.Get ? "query" : "body";
                    apiParameter.Schema = GetSwaggerItemSchema(p.PropertyType, definitions, config);
                }
                pathParameters.Add(apiParameter);
            });
        }
        private void CreateSwaggerDefinition(string name, Type definitionType, Dictionary <string, SwaggerDefinition> definitions, SwaggerConfig config)
        {
            if (definitions.ContainsKey(name))
            {
                return;
            }

            if ("Type".Equals(name))
            {
                return;
            }

            SwaggerDefinition definition = new SwaggerDefinition
            {
                Type       = "object",
                Properties = new Dictionary <string, SwaggerPropertyDefinition>()
            };


            var properties = definitionType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

            properties.ForEach(p =>
            {
                SwaggerPropertyDefinition pd = new SwaggerPropertyDefinition
                {
                    Description = this._resolver.GetMemberInfoComment(p)
                };

                if (p.PropertyType == typeof(string) || p.PropertyType.IsValueType)
                {
                    pd.Type = GetSwaggerType(p.PropertyType);
                }
                else if (p.PropertyType.IsArray && p.PropertyType.HasElementType)
                {
                    pd.Type  = "array";
                    pd.Items = GetSwaggerItemSchema(p.PropertyType.GetElementType(), definitions, config);
                }
                else if (
                    typeof(System.Collections.ICollection).IsAssignableFrom(p.PropertyType) ||
                    typeof(System.Collections.IEnumerable).IsAssignableFrom(p.PropertyType)
                    )
                {
                    if (p.PropertyType.IsGenericType)
                    {
                        pd.Type  = "array";
                        pd.Items = GetSwaggerItemSchema(p.PropertyType.GenericTypeArguments[0], definitions, config);
                    }
                    else
                    {
                        pd.Type = "array";
                    }
                }
                else
                {
                    //Console.WriteLine(p.PropertyType.Name);
                    pd.Ref = "#/definitions/" + p.PropertyType.Name;
                    CreateSwaggerDefinition(p.PropertyType.Name, p.PropertyType, definitions, config);
                }

                definition.Properties.Add(p.Name.ToCamelCase(), pd);
            });

            definitions.Add(name, definition);
        }
        private void ProcessResponses(Dictionary <string, SwaggerApiResponse> pathResponses,
                                      ParameterInfo invokeMethodReturnParameter, Dictionary <string, SwaggerDefinition> definitions, SwaggerConfig config)
        {
            //Task<RpcResult>
            if (!invokeMethodReturnParameter.ParameterType.IsGenericType)
            {
                return;
            }
            var rpcResultType = invokeMethodReturnParameter.ParameterType.GenericTypeArguments[0];

            if (!rpcResultType.IsGenericType) //Task<RpcResult>
            {
                return;
            }
            //Task<RpcResult<T>>
            var innerType = rpcResultType.GenericTypeArguments[0];

            SwaggerApiResponse apiResponse = new SwaggerApiResponse
            {
                Description = this._resolver.GetTypeComment(innerType),
                Schema      = GetSwaggerItemSchema(innerType, definitions, config)
            };

            pathResponses.Add("200", apiResponse);

            //Console.WriteLine(innerType.FullName);
            //Console.WriteLine("---------------------------------------------------");
            CreateSwaggerDefinition(innerType.Name, innerType, definitions, config);
        }