public OperationSpec ApiDescriptionToOperationSpec(ApiDescription apiDescription, ModelSpecRegistrar modelSpecRegistrar)
        {
            var apiPath    = apiDescription.RelativePathSansQueryString();
            var paramSpecs = apiDescription.ParameterDescriptions
                             .Select(paramDesc => CreateParameterSpec(paramDesc, apiPath, modelSpecRegistrar))
                             .ToList();

            var operationSpec = new OperationSpec
            {
                Method           = apiDescription.HttpMethod.Method,
                Nickname         = apiDescription.Nickname(),
                Summary          = apiDescription.Documentation,
                Parameters       = paramSpecs,
                ResponseMessages = new List <ResponseMessageSpec>()
            };

            var returnType = apiDescription.ActionDescriptor.ReturnType;

            if (returnType == null)
            {
                operationSpec.Type = "void";
            }
            else
            {
                IEnumerable <ModelSpec> complexSpecs;
                var modelSpec = _modelSpecGenerator.TypeToModelSpec(returnType, out complexSpecs);

                modelSpecRegistrar.RegisterMany(complexSpecs);

                if (modelSpec.Type == "object")
                {
                    operationSpec.Type = modelSpec.Id;
                }
                else
                {
                    operationSpec.Type   = modelSpec.Type;
                    operationSpec.Format = modelSpec.Format;
                    operationSpec.Items  = modelSpec.Items;
                    operationSpec.Enum   = modelSpec.Enum;
                }
            }

            foreach (var filter in _operationFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecRegistrar, _modelSpecGenerator);
            }

            // IOperationSpecFilter is obsolete - below is for back-compat
            var modelSpecMap = new ModelSpecMap(modelSpecRegistrar, _modelSpecGenerator);

            foreach (var filter in _operationSpecFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecMap);
            }

            return(operationSpec);
        }
        public OperationSpec ApiDescriptionToOperationSpec(ApiDescription apiDescription, ModelSpecRegistrar modelSpecRegistrar)
        {
            var apiPath = apiDescription.RelativePathSansQueryString();
            var paramSpecs = apiDescription.ParameterDescriptions
                .Select(paramDesc => CreateParameterSpec(paramDesc, apiPath, modelSpecRegistrar))
                .ToList();

            var operationSpec = new OperationSpec
            {
                Method = apiDescription.HttpMethod.Method,
                Nickname = apiDescription.Nickname(),
                Summary = apiDescription.Documentation,
                Parameters = paramSpecs,
                ResponseMessages = new List<ResponseMessageSpec>()
            };

            var returnType = apiDescription.ActionDescriptor.ReturnType;
            if (returnType == null)
            {
                operationSpec.Type = "void";
            }
            else
            {
                IEnumerable<ModelSpec> complexSpecs;
                var modelSpec = _modelSpecGenerator.TypeToModelSpec(returnType, out complexSpecs);

                modelSpecRegistrar.RegisterMany(complexSpecs);

                if (modelSpec.Type == "object")
                {
                    operationSpec.Type = modelSpec.Id;
                }
                else
                {
                    operationSpec.Type = modelSpec.Type;
                    operationSpec.Format = modelSpec.Format;
                    operationSpec.Items = modelSpec.Items;
                    operationSpec.Enum = modelSpec.Enum;
                }
            }

            foreach (var filter in _operationFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecRegistrar, _modelSpecGenerator);
            }

            // IOperationSpecFilter is obsolete - below is for back-compat
            var modelSpecMap = new ModelSpecMap(modelSpecRegistrar, _modelSpecGenerator);
            foreach (var filter in _operationSpecFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecMap);
            }

            return operationSpec;
        }
 public void Apply(ApiDescription apiDescription, OperationSpec operationSpec, ModelSpecMap modelSpecMap)
 {
     if (apiDescription.ActionDescriptor.GetFilters().OfType<AuthorizeAttribute>().Any())
     {
         operationSpec.ResponseMessages.Add(new ResponseMessageSpec
             {
                 Code = (int) HttpStatusCode.Unauthorized,
                 Message = "Authentication required"
             });
     }
 }
        public OperationSpec From(ApiDescription apiDescription, ModelSpecRegistrar modelSpecRegistrar)
        {
            var apiPath = apiDescription.RelativePath.Split('?').First();
            var paramSpecs = apiDescription.ParameterDescriptions
                .Select(paramDesc => CreateParameterSpec(paramDesc, apiPath, modelSpecRegistrar))
                .ToList();

            var operationSpec = new OperationSpec
            {
                Method = apiDescription.HttpMethod.Method,
                Nickname = String.Format("{0}_{1}",
                    apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName,
                    apiDescription.ActionDescriptor.ActionName),
                Summary = apiDescription.Documentation,
                Parameters = paramSpecs,
                ResponseMessages = new List<ResponseMessageSpec>()
            };

            var returnType = apiDescription.ActionDescriptor.ReturnType;
            if (returnType == null)
            {
                operationSpec.Type = "void";
            }
            else
            {
                var modelSpec = _modelSpecGenerator.From(returnType, modelSpecRegistrar);

                if (modelSpec.Type == "object")
                {
                    operationSpec.Type = modelSpec.Id;
                }
                else
                {
                    operationSpec.Type = modelSpec.Type;
                    operationSpec.Format = modelSpec.Format;
                    operationSpec.Items = modelSpec.Items;
                    operationSpec.Enum = modelSpec.Enum;
                }
            }

            foreach (var filter in _operationFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecRegistrar, _modelSpecGenerator);
            }

            // IOperationSpecFilter is obsolete - below is for back-compat
            var modelSpecMap = new ModelSpecMap(modelSpecRegistrar, _modelSpecGenerator);
            foreach (var filter in _operationSpecFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecMap);
            }

            return operationSpec;
        }
        private ApiSpec GenerateApiSpec(IGrouping<string, ApiDescription> apiDescriptionGroup, ModelSpecMap modelSpecMap)
        {
            var operationSpecs = apiDescriptionGroup
                .Select(apiDesc => GenerateOperationSpec(apiDesc, modelSpecMap))
                .ToList();

            return new ApiSpec
            {
                Path = "/" + apiDescriptionGroup.Key.Split('?').First(),
                Operations = operationSpecs
            };
        }
        public void Apply(ApiDescription apiDescription, OperationSpec operationSpec, ModelSpecMap modelSpecMap)
        {
            operationSpec.ResponseMessages.Add(new ResponseMessageSpec
                {
                    Code = (int) HttpStatusCode.OK,
                    Message = "It's all good!"
                });

            operationSpec.ResponseMessages.Add(new ResponseMessageSpec
            {
                Code = (int)HttpStatusCode.InternalServerError,
                Message = "Somethings up!"
            });
        }
        public void Apply(ApiDescription apiDescription, OperationSpec operationSpec, ModelSpecMap modelSpecMap)
        {
            var descriptionXml = XElement.Parse(apiDescription.Documentation);

            var summary = descriptionXml.Element("summary");
            operationSpec.Summary = summary != null ? summary.Value : descriptionXml.Value;

            var notes = descriptionXml.Element("remarks");
            if (notes != null)
                operationSpec.Notes = notes.Value;

            foreach (var error in descriptionXml.Elements("response"))
            {
                operationSpec.ResponseMessages.Add(new ResponseMessageSpec() { Code = Convert.ToInt32(error.Attribute("code").Value), Message = error.Value });
            }
        }
        private ApiDeclaration GenerateDeclaration(IGrouping<string, ApiDescription> apiDescriptionGroup)
        {
            var modelSpecMap = new ModelSpecMap(_customTypeMappings);

            // Group further by relative path - each group corresponds to an ApiSpec
            var apiSpecs = apiDescriptionGroup
                .GroupBy(apiDesc => apiDesc.RelativePath)
                .Select(apiDescGrp => GenerateApiSpec(apiDescGrp, modelSpecMap))
                .ToList();

            var complexModelSpecs = modelSpecMap.GetAll()
                .Where(modelSpec => modelSpec.Type == "object")
                .ToDictionary(modelSpec => modelSpec.Id, modelSpec => modelSpec);

            return new ApiDeclaration
            {
                ApiVersion = "1.0",
                SwaggerVersion = SwaggerVersion,
                BasePath = _basePathResolver().TrimEnd('/'),
                ResourcePath = apiDescriptionGroup.Key,
                Apis = apiSpecs,
                Models = complexModelSpecs
            };
        }
        private ParameterSpec GenerateParameterSpec(ApiParameterDescription parameterDescription, string apiPath, ModelSpecMap modelSpecMap)
        {
            var paramType = "";
            switch (parameterDescription.Source)
            {
                case ApiParameterSource.FromBody:
                    paramType = "body";
                    break;
                case ApiParameterSource.FromUri:
                    paramType = apiPath.Contains(parameterDescription.Name) ? "path" : "query";
                    break;
            }

            var paramSpec = new ParameterSpec
            {
                ParamType = paramType,
                Name = parameterDescription.Name,
                Description = parameterDescription.Documentation,
                Required = !parameterDescription.ParameterDescriptor.IsOptional
            };

            var modelSpec = modelSpecMap.FindOrCreateFor(parameterDescription.ParameterDescriptor.ParameterType);
            if (modelSpec.Type == "object")
            {
                paramSpec.Type = modelSpec.Id;
            }
            else
            {
                paramSpec.Type = modelSpec.Type;
                paramSpec.Format = modelSpec.Format;
                paramSpec.Items = modelSpec.Items;
                paramSpec.Enum = modelSpec.Enum;
            }

            return paramSpec;
        }
        private OperationSpec GenerateOperationSpec(ApiDescription apiDescription, ModelSpecMap modelSpecMap)
        {
            var apiPath = apiDescription.RelativePath.Split('?').First();
            var paramSpecs = apiDescription.ParameterDescriptions
                .Select(paramDesc => GenerateParameterSpec(paramDesc, apiPath, modelSpecMap))
                .ToList();

            var operationSpec = new OperationSpec
            {
                Method = apiDescription.HttpMethod.Method,
                Nickname = String.Format("{0}_{1}",
                    apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName,
                    apiDescription.ActionDescriptor.ActionName),
                Summary = apiDescription.Documentation,
                Parameters = paramSpecs,
                ResponseMessages = new List<ResponseMessageSpec>()
            };

            var returnType = apiDescription.ActionDescriptor.ReturnType;
            if (returnType == null)
            {
                operationSpec.Type = "void";
            }
            else if (returnType != typeof(HttpResponseMessage))
            {
                var modelSpec = modelSpecMap.FindOrCreateFor(returnType);
                if (modelSpec.Type == "object")
                {
                    operationSpec.Type = modelSpec.Id;
                }
                else
                {
                    operationSpec.Type = modelSpec.Type;
                    operationSpec.Format = modelSpec.Format;
                    operationSpec.Items = modelSpec.Items;
                    operationSpec.Enum = modelSpec.Enum;
                }
            }

            foreach (var filter in _operationSpecFilters)
            {
                filter.Apply(apiDescription, operationSpec, modelSpecMap);
            }

            return operationSpec;
        }