Accesses the XML doc blocks written in code to further document the API. All credit goes to: http://blogs.msdn.com/b/yaohuang1/archive/2012/05/21/asp-net-web-api-generating-a-web-api-help-page-using-apiexplorer.aspx
Inheritance: IDocumentationProvider
        private ResourceListing getDocs(HttpActionContext actionContext)
        {
            var assemblyType = (actionContext.ActionDescriptor as ReflectedHttpActionDescriptor).MethodInfo.DeclaringType;
            var docProvider  = new XmlCommentDocumentationProvider(); //(XmlCommentDocumentationProvider)GlobalConfiguration.Configuration.Services.GetDocumentationProvider();

            ResourceListing r = SwaggerGen.CreateResourceListing(actionContext);

            foreach (var api in GlobalConfiguration.Configuration.Services.GetApiExplorer().ApiDescriptions)
            {
                if (api.ActionDescriptor.ActionName.EndsWith("API"))//Ignore each Default API action
                {
                    continue;
                }

                string apiControllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
                if (api.Route.Defaults.ContainsKey(SwaggerGen.SWAGGER) ||
                    apiControllerName.ToUpper().Equals(SwaggerGen.SWAGGER.ToUpper()))
                {
                    continue;
                }

                // Make sure we only report the current controller docs
                if (!apiControllerName.Equals(actionContext.ControllerContext.ControllerDescriptor.ControllerName))
                {
                    continue;
                }

                ResourceApi rApi = SwaggerGen.CreateResourceApi(api);
                r.apis.Add(rApi);

                ResourceApiOperation rApiOperation = SwaggerGen.CreateResourceApiOperation(r, api, docProvider);
                rApi.operations.Add(rApiOperation);

                foreach (var param in api.ParameterDescriptions)
                {
                    ResourceApiOperationParameter parameter = SwaggerGen.CreateResourceApiOperationParameter(r, api, param, docProvider);
                    rApiOperation.parameters.Add(parameter);
                }

                if (System.Configuration.ConfigurationManager.AppSettings["swagger:APITOKEN"] != null &&
                    System.Configuration.ConfigurationManager.AppSettings["swagger:APITOKEN"].Equals("true") &&
                    !api.ActionDescriptor.ActionName.EndsWith("API"))
                {
                    //添加Token
                    ResourceApiOperationParameter p = new ResourceApiOperationParameter();
                    p.name        = "ApiToken";
                    p.description = "Api Token";
                    p.paramType   = "path";
                    p.required    = true;
                    p.dataType    = "String";
                    rApiOperation.parameters.Insert(0, p);
                }

                SwaggerGen.CreateModel(r, api, docProvider);
                //r.models = new ResourceApiModel();
            }

            return(r);
        }
Exemple #2
0
        private static bool IsRequired(PropertyInfo propertyInfo, XmlCommentDocumentationProvider docProvider)
        {
            if (propertyInfo.PropertyType.IsGenericType &&
                propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                return(false);
            }

            return(docProvider.IsRequired(propertyInfo));
        }
Exemple #3
0
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            ResourceApiOperation rApiOperation = new ResourceApiOperation()
            {
                httpMethod = api.HttpMethod.ToString(),
                nickname = docProvider.GetNickname(api.ActionDescriptor),
                responseClass = docProvider.GetResponseClass(api.ActionDescriptor),
                summary = api.Documentation,
                notes = docProvider.GetNotes(api.ActionDescriptor),
                parameters = new List<ResourceApiOperationParameter>()
            };

            return rApiOperation;
        }
Exemple #4
0
        public static Dictionary<string,Model> CreateModels(IEnumerable<ApiDescription> apiDescriptions, XmlCommentDocumentationProvider docProvider)
        {
            var parameters = apiDescriptions.SelectMany(a => a.ParameterDescriptions)
                                .Where(p => !p.ParameterDescriptor.ParameterType.IsPrimitive());

            var models = new Dictionary<string,Model>();
            foreach (var param in parameters)
            {
                if (!models.ContainsKey(param.ParameterDescriptor.ParameterType.Name))
                {
                    var model = new Model()
                        {
                            Id = param.ParameterDescriptor.ParameterType.Name,
                            Properties = CreateProperties(param.ParameterDescriptor.ParameterType)
                        };
                    models.Add(param.ParameterDescriptor.ParameterType.Name, model);
                }
            }
            return models;
        }
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ResourceListing r, ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;
            var    dataType  = param.ParameterDescriptor.ParameterType.Name;

            switch (dataType)
            {
            case "List`1":
                var dataObjType = param.ParameterDescriptor.ParameterType.GetGenericArguments()[0];
                dataType = string.Format("Array[{0}]", dataObjType.Name);
                break;

            case "Nullable`1":
                var dd = param.ParameterDescriptor.ParameterType.GetGenericArguments()[0];
                dataType = dd.Name;
                break;

            case "Dictionary`2":

                dataType = string.Format("Array[{0},{1}]", param.ParameterDescriptor.ParameterType.GetGenericArguments()[0].Name,
                                         param.ParameterDescriptor.ParameterType.GetGenericArguments()[1].Name);
                break;

            default:
                if (param.ParameterDescriptor.ParameterType.IsPrimitive)
                {
                    if (!IsExceptType(param.ParameterDescriptor.ParameterType))
                    {
                        AddModelDataObject(r, param.ParameterDescriptor.ParameterType);
                    }
                }
                else
                {
                    foreach (var item in param.ParameterDescriptor.ParameterType.GetProperties())
                    {
                        ResourceApiOperationParameter parametera = new ResourceApiOperationParameter()
                        {
                            paramType   = (paramType == "query" && api.RelativePath.IndexOf("{" + item.Name + "}") > -1) ? PATH : paramType,
                            name        = item.Name,
                            description = GetDocumentation(param.ParameterDescriptor.ParameterType),    // string.IsNullOrWhiteSpace(param.Documentation) ? NODESCRIPTION : param.Documentation,
                            dataType    = dataType,
                            required    = docProvider.GetRequired(param.ParameterDescriptor)
                        };

                        if (string.IsNullOrWhiteSpace(parametera.description) || NODESCRIPTION.Equals(parametera.description, StringComparison.OrdinalIgnoreCase))
                        {
                            parametera.description = GetParameterDocumentation((param.ParameterDescriptor as ReflectedHttpParameterDescriptor).ParameterInfo, api.ActionDescriptor.ControllerDescriptor.ControllerType);
                        }
                    }
                }
                break;
            }
            ResourceApiOperationParameter parameter = new ResourceApiOperationParameter()
            {
                paramType   = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name        = param.Name,
                description = param.Name.Equals("sessionKey")
                ? "Login session" : (string.IsNullOrWhiteSpace(param.Documentation) ? NODESCRIPTION : param.Documentation),
                dataType = dataType,
                required = docProvider.GetRequired(param.ParameterDescriptor)
            };

            if (string.IsNullOrWhiteSpace(parameter.description) || NODESCRIPTION.Equals(parameter.description, StringComparison.OrdinalIgnoreCase))
            {
                parameter.description = GetParameterDocumentation((param.ParameterDescriptor as ReflectedHttpParameterDescriptor).ParameterInfo, api.ActionDescriptor.ControllerDescriptor.ControllerType);
            }

            return(parameter);
        }
Exemple #6
0
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api, XmlCommentDocumentationProvider docProvider, DataTypeRegistry dataTypeRegistry)
        {
            ResourceApiOperation rApiOperation = new ResourceApiOperation()
            {
                httpMethod       = api.HttpMethod.ToString(),
                nickname         = docProvider.GetNickname(api.ActionDescriptor),
                responseClass    = docProvider.GetResponseClass(api.ActionDescriptor),
                summary          = api.Documentation,
                notes            = docProvider.GetNotes(api.ActionDescriptor),
                type             = docProvider.GetResponseClass(api.ActionDescriptor),
                parameters       = new List <ResourceApiOperationParameter>(),
                responseMessages = new List <ResourceApiOperationResponseMessage>(),
            };

            var responseType = api.ActualResponseType();

            if (responseType == null)
            {
                rApiOperation.type = "void";
            }
            else
            {
                var dataType = dataTypeRegistry.GetOrRegister(responseType);
                if (dataType.Type == "object")
                {
                    rApiOperation.type = dataType.Id;
                }
                else
                {
                    rApiOperation.type   = dataType.Type;
                    rApiOperation.format = dataType.Format;
                    rApiOperation.items  = dataType.Items;
                    rApiOperation.Enum   = dataType.Enum;
                }
            }

            return(rApiOperation);
        }
Exemple #7
0
        public static void TryToAddModels(ConcurrentDictionary<string, TypeInfo> models, Type type, XmlCommentDocumentationProvider docProvider, ConcurrentDictionary<string, string> typesToReturn = null, int level = 0)
        {
            var _type = type;
            if (type.IsArray)
                _type = type.GetElementType();
            else if (type.IsGenericType)
                _type = type.GetGenericArguments().First();

            string typeName = GetTypeName(_type);

            if (models.Any(m => m.Key == typeName)) return;
            
            if (IsOutputable(_type))
            {
                var typeInfo = new TypeInfo { id = typeName };
                if (!IgnoreTypes.Contains(_type.Name.ToLower()))
                {
                    typeInfo.description = docProvider.GetSummary(_type);
                }
                //Ignore properties for .net types
                if (!_type.Assembly.FullName.Contains("System") && !_type.Assembly.FullName.Contains("mscorlib"))
                {
                    var modelInfoDic = new Dictionary<string, PropInfo>();
                    foreach (var propertyInfo in _type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        if (propertyInfo.GetCustomAttributes(typeof(JsonIgnoreAttribute), false).FirstOrDefault() != null)
                            continue;

                        var propInfo = new PropInfo();

                        string propName = GetPropertyName(propertyInfo);
                        Type propType = docProvider.GetType(propertyInfo);
                        SwaggerType swaggerType = GetSwaggerType(propType);
                        propInfo.type = swaggerType.Name;
                        propInfo.items = swaggerType.Items;
                        propInfo.required = IsRequired(propertyInfo, docProvider);


                        if (!modelInfoDic.Keys.Contains(propName))
                            modelInfoDic.Add(propName, propInfo);

                        if (!IgnoreTypes.Contains(propInfo.type))
                        {
                            propInfo.description = docProvider.GetSummary(propertyInfo);
                            if (propertyInfo.PropertyType.IsEnum)
                            {
                                modelInfoDic[propName].@enum = propertyInfo.PropertyType.GetEnumNames();
                            }
                            //Don't go too deep
                            if (level < 10)
                            {
                                TryToAddModels(models, swaggerType.type, docProvider, typesToReturn, ++level);
                            }
                        }
                    }
                    typeInfo.properties = modelInfoDic;
                }
                if (_type.IsEnum)
                {
                    typeInfo.values = _type.GetEnumNames();
                }

                models.TryAdd(typeName, typeInfo);
            }
        }
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;

            var parameter = new ResourceApiOperationParameter()
            {
                paramType   = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name        = param.Name,
                description = param.Documentation,
                dataType    = TypeParser.Parse(param.ParameterDescriptor.ParameterType),
                required    = docProvider.GetRequired(param.ParameterDescriptor)
            };

            parameter.allowMultiple   = parameter.dataType.StartsWith("List[");
            parameter.allowableValues = CreateAllowableValues(param.ParameterDescriptor.ParameterType);

            CustomAttributeHelper.PrepareByOptionAttribute(parameter, param.ParameterDescriptor);

            return(parameter);
        }
        private static IList <ResourceModelNode> CreateResourceModel(ApiParameterDescription param, Type modelType, XmlCommentDocumentationProvider docProvider)
        {
            lock (s_lock)
            {
                var result = new List <ResourceModelNode>();
                ResourceModelNode rModel = null;

                if ((!modelType.IsEnum && !modelType.Equals(typeof(string))))
                {
                    if (modelType.IsGenericType)
                    {
                        modelType = modelType.GetGenericArguments().First();
                        return(CreateResourceModel(param, modelType, docProvider));
                    }

                    if (s_cache.ContainsKey(modelType))
                    {
                        result.AddRange(s_cache[modelType]);
                        return(result);
                    }


                    rModel = new ResourceModelNode()
                    {
                        Id = TypeParser.Parse(modelType.Name)
                    };

                    s_cache.Add(modelType, result);

                    foreach (var typeProperty in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        var property = new ResourceModelPropertyNode();
                        property.Id   = TypeParser.Parse(typeProperty.Name);
                        property.Type = TypeParser.Parse(typeProperty.PropertyType);

                        if (typeProperty.PropertyType.IsValueType || Nullable.GetUnderlyingType(typeProperty.PropertyType) == null)
                        {
                            rModel.Required.Add(property.Id);
                        }

                        if (property.Type.StartsWith("List["))
                        {
                            property.Type = "array";

                            var itemType = typeProperty.PropertyType.GetGenericArguments().FirstOrDefault();

                            if (itemType == null)
                            {
                                itemType = typeProperty.PropertyType;
                            }

                            property.DefineContainerType(itemType);
                        }

                        result.AddRange(CreateResourceModel(typeProperty.PropertyType, docProvider));

                        if (docProvider != null)
                        {
                            property.Description = docProvider.GetDocumentation(typeProperty);

                            if (typeProperty.PropertyType.IsEnum)
                            {
                                property.AllowableValues = CreateAllowableValues(typeProperty.PropertyType);
                            }
                            else if ((typeProperty.PropertyType.IsClass || typeProperty.PropertyType.IsValueType) && typeof(string) != typeProperty.PropertyType)
                            {
                                result.AddRange(CreateResourceModel(typeProperty.PropertyType, docProvider));
                            }
                        }

                        rModel.Properties.Add(property);
                    }

                    if (rModel.Properties.Count > 0)
                    {
                        result.Add(rModel);
                    }
                }

                return(result);
            }
        }
 public static IList <ResourceModelNode> CreateResourceModel(ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
 {
     return(CreateResourceModel(param, param.ParameterDescriptor.ParameterType, docProvider));
 }
Exemple #11
0
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;
            ResourceApiOperationParameter parameter = new ResourceApiOperationParameter()
            {
                paramType = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name = param.Name,
                description = param.Documentation,
                dataType = param.ParameterDescriptor.ParameterType.Name,
                required = docProvider.GetRequired(param.ParameterDescriptor)
            };

            return parameter;
        }
 public static IList<ResourceModelNode> CreateResourceModel(Type modelType, XmlCommentDocumentationProvider docProvider)
 {
     return CreateResourceModel(null, modelType, docProvider);
 }
 public static IList<ResourceModelNode> CreateResourceModel(ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
 {
     return CreateResourceModel(param, param.ParameterDescriptor.ParameterType, docProvider);
 }
Exemple #14
0
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            ResponseMeta responseMeta = docProvider.GetResponseType(api.ActionDescriptor);
            SwaggerType  swaggerType  = Helper.GetSwaggerType(responseMeta.Type);


            ResourceApiOperation rApiOperation = new ResourceApiOperation
            {
                httpMethod       = api.HttpMethod.ToString(),
                nickname         = docProvider.GetNickname(api.ActionDescriptor),
                items            = swaggerType.Items,
                type             = swaggerType.Name,
                summary          = api.Documentation,
                notes            = docProvider.GetNotes(api.ActionDescriptor),
                parameters       = new List <ResourceApiOperationParameter>(),
                responseMessages = docProvider.GetResponseCodes(api.ActionDescriptor)
            };

            var typesToReturn = new ConcurrentDictionary <string, string>();

            Helper.TryToAddModels(models, responseMeta.Type, docProvider, typesToReturn);
            return(rApiOperation);
        }
Exemple #15
0
        public static Dictionary <string, Model> CreateModels(IEnumerable <ApiDescription> apiDescriptions, XmlCommentDocumentationProvider docProvider)
        {
            var parameters = apiDescriptions.SelectMany(a => a.ParameterDescriptions)
                             .Where(p => !p.ParameterDescriptor.ParameterType.IsPrimitive());

            var models = new Dictionary <string, Model>();

            foreach (var param in parameters)
            {
                if (!models.ContainsKey(param.ParameterDescriptor.ParameterType.Name))
                {
                    var model = new Model()
                    {
                        Id         = param.ParameterDescriptor.ParameterType.Name,
                        Properties = CreateProperties(param.ParameterDescriptor.ParameterType)
                    };
                    models.Add(param.ParameterDescriptor.ParameterType.Name, model);
                }
            }
            return(models);
        }
Exemple #16
0
 public SwaggerGen()
 {
     _docProvider =
         (XmlCommentDocumentationProvider)GlobalConfiguration.Configuration.Services.GetDocumentationProvider();
 }
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api,
            XmlCommentDocumentationProvider docProvider, HttpControllerDescriptor controllerDescriptor)

        {
            var parts = docProvider.GetNotes(api.ActionDescriptor).Split(new string[] { "schema=" }, StringSplitOptions.None);
            ReflectedHttpActionDescriptor actionDescriptor = (api.ActionDescriptor as ReflectedHttpActionDescriptor);
            string _attributes = "";
            _attributes += GetCustomAttributesAsString(actionDescriptor.MethodInfo.GetCustomAttributes(true));
            _attributes += GetCustomAttributesAsString(controllerDescriptor.ControllerType.GetCustomAttributes(true));
            
            ResourceApiOperation rApiOperation = new ResourceApiOperation()
            {
                httpMethod = api.HttpMethod.ToString(),
                nickname = docProvider.GetNickname(api.ActionDescriptor),
                responseClass = docProvider.GetResponseClass(api.ActionDescriptor),
                summary = api.Documentation+" "+_attributes,
                notes = parts[0],
                schema = parts.Length > 1 ? parts[1] : "",
                parameters = new List<ResourceApiOperationParameter>(),
            };

            return rApiOperation;
        }
        private static IList<ResourceModelNode> CreateResourceModel(ApiParameterDescription param, Type modelType, XmlCommentDocumentationProvider docProvider)
        {
            lock (s_lock)
            {
                var result = new List<ResourceModelNode>();
                ResourceModelNode rModel = null;

                if ((!modelType.IsEnum && !modelType.Equals(typeof(string))))
                {
                    if (modelType.IsGenericType)
                    {
                        modelType = modelType.GetGenericArguments().First();
                        return CreateResourceModel(param, modelType, docProvider);
                    }

                    if (s_cache.ContainsKey(modelType))
                    {
                        result.AddRange(s_cache[modelType]);
                        return result;
                    }


                    rModel = new ResourceModelNode()
                    {
                        Id = TypeParser.Parse(modelType.Name)
                    };

                    s_cache.Add(modelType, result);

                    foreach (var typeProperty in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        var property = new ResourceModelPropertyNode();
                        property.Id = TypeParser.Parse(typeProperty.Name);
                        property.Type = TypeParser.Parse(typeProperty.PropertyType);

                        if (typeProperty.PropertyType.IsValueType || Nullable.GetUnderlyingType(typeProperty.PropertyType) == null)
                        {
                            rModel.Required.Add(property.Id);
                        }

                        if (property.Type.StartsWith("List["))
                        {
                            property.Type = "array";

                            var itemType = typeProperty.PropertyType.GetGenericArguments().FirstOrDefault();

                            if (itemType == null)
                            {
                                itemType = typeProperty.PropertyType;
                            }

                            property.DefineContainerType(itemType);
                        }

                        result.AddRange(CreateResourceModel(typeProperty.PropertyType, docProvider));

                        if (docProvider != null)
                        {
                            property.Description = docProvider.GetDocumentation(typeProperty);

                            if (typeProperty.PropertyType.IsEnum)
                            {
                                property.AllowableValues = CreateAllowableValues(typeProperty.PropertyType);

                            }
                            else if ((typeProperty.PropertyType.IsClass || typeProperty.PropertyType.IsValueType) && typeof(string) != typeProperty.PropertyType)
                            {
                                result.AddRange(CreateResourceModel(typeProperty.PropertyType, docProvider));

                            }
                        }

                        rModel.Properties.Add(property);
                    }

                    if (rModel.Properties.Count > 0)
                    {
                        result.Add(rModel);
                    }
                }

                return result;
            }
        }
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;

            var parameter = new ResourceApiOperationParameter()
            {
                paramType = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name = param.Name,
                description = param.Documentation,
                dataType = TypeParser.Parse(param.ParameterDescriptor.ParameterType),
                required = docProvider.GetRequired(param.ParameterDescriptor)
            };

            parameter.allowMultiple = parameter.dataType.StartsWith("List[");
            parameter.allowableValues = CreateAllowableValues(param.ParameterDescriptor.ParameterType);

            CustomAttributeHelper.PrepareByOptionAttribute(parameter, param.ParameterDescriptor);

            return parameter;
        }
Exemple #20
0
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;
            ResourceApiOperationParameter parameter = new ResourceApiOperationParameter()
            {
                paramType   = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name        = param.Name,
                description = param.Documentation,
                dataType    = param.ParameterDescriptor.ParameterType.Name,
                required    = docProvider.GetRequired(param.ParameterDescriptor)
                              //allowableValues = new OperationParameterAllowableValues()
            };

            return(parameter);
        }
Exemple #21
0
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            ResponseMeta responseMeta = docProvider.GetResponseType(api.ActionDescriptor);
            SwaggerType swaggerType = Helper.GetSwaggerType(responseMeta.Type);


            ResourceApiOperation rApiOperation = new ResourceApiOperation
            {
                httpMethod = api.HttpMethod.ToString(),
                nickname = docProvider.GetNickname(api.ActionDescriptor),
                items = swaggerType.Items,
                type = swaggerType.Name,
                summary = api.Documentation,
                notes = docProvider.GetNotes(api.ActionDescriptor),
                parameters = new List<ResourceApiOperationParameter>(),
                responseMessages = docProvider.GetResponseCodes(api.ActionDescriptor)
            };

            var typesToReturn = new ConcurrentDictionary<string, string>();
            Helper.TryToAddModels(models, responseMeta.Type, docProvider, typesToReturn);
            return rApiOperation;
        }
 public static IList <ResourceModelNode> CreateResourceModel(Type modelType, XmlCommentDocumentationProvider docProvider)
 {
     return(CreateResourceModel(null, modelType, docProvider));
 }
Exemple #23
0
        public static void CreateModel(ResourceListing r, ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            if (r.models == null)
            {
                r.models = new ConcurrentDictionary <string, object>();
            }

            ReflectedHttpActionDescriptor reflectedActionDescriptor = api.ActionDescriptor as ReflectedHttpActionDescriptor;

            if (reflectedActionDescriptor != null)
            {
                //this function will be called generating swagger API json
                //limitations
                //-only generating swagger models (API return type documentation) for return type is ApiResponse
                //--most calls fall into these 3 categories:
                //--ApiResponse<PageData<T>>
                //--ApiResponse<T>
                //--ApiResponse<T> where T is simple type such as object, string, int, etc.
                //-only generate detail when T is DataObject

                //implementation notes
                //-get the actual T
                //--when T is DataObject, add into a queue (i.e. a FIFO Stack) for next step processing
                //-loop until queue is empty
                //--process (add model details) for the first item in queue, remove it after processed
                //--during the processing, if found any property is type of DataObject, add the nested type into queue
                //-the reason to use a while loop with a queue is to avoid using recursive implementation which will throw a stack-overflow exception when it's too many nested types

                var         returnType = reflectedActionDescriptor.MethodInfo.ReturnType;
                List <Type> queue      = new List <Type>();//process queue
                AddTypeToProcessQueue(r, returnType, queue);
                //parameter handling
                var parameters = reflectedActionDescriptor.MethodInfo.GetParameters();
                if (parameters != null && parameters.Length > 0)
                {
                    foreach (var p in parameters)
                    {
                        if (p.ParameterType.IsGenericType)
                        {
                            var dataObjType = p.ParameterType.GetGenericArguments()[0];
                            AddTypeToProcessQueue(r, dataObjType, queue);
                        }
                        else
                        {
                            AddTypeToProcessQueue(r, p.ParameterType, queue);
                        }
                    }
                }
                if (returnType.IsGenericType)
                {
                    Type[] types = returnType.GetGenericArguments();
                    if (types[0].Name.Equals("PageData`1"))
                    {
                        var dataObjType = types[0].GetGenericArguments()[0];
                        AddTypeToProcessQueue(r, dataObjType, queue);
                        //ApiResponse_PageData_xxxxx
                        var model = AddModelApiResponse(r, "ApiResponse_PageData_" + dataObjType.Name);
                        if (model != null)
                        {
                            var p = new ResourceApiModelProperty();
                            p.type        = "Array";
                            p.description = "Page data set";
                            var items = new Dictionary <string, string>();
                            items.Add("$ref", "PageData_" + dataObjType.Name);
                            p.items = items;
                            model.properties.Add("Results", p);
                        }
                        if (!r.models.ContainsKey("PageData_" + dataObjType.Name))
                        {
                            model            = new ResourceApiModel();
                            model.id         = "PageData_" + dataObjType.Name;
                            model.properties = new Dictionary <string, ResourceApiModelProperty>();
                            var p = new ResourceApiModelProperty();
                            p.type        = "int";
                            p.description = "total no of qualified data";
                            model.properties.Add("TotalRecords", p);

                            p             = new ResourceApiModelProperty();
                            p.type        = "bool";
                            p.description = "whether has next page";
                            model.properties.Add("HasNextPage", p);

                            p             = new ResourceApiModelProperty();
                            p.type        = "int";
                            p.description = "curent page index, start from 0";
                            model.properties.Add("PageIndex", p);

                            p             = new ResourceApiModelProperty();
                            p.type        = "int";
                            p.description = "how many records in one page";
                            model.properties.Add("PageSize", p);

                            p             = new ResourceApiModelProperty();
                            p.type        = "Array";
                            p.description = "A page of data";
                            var items = new Dictionary <string, string>();
                            items.Add("$ref", dataObjType.Name);
                            p.items = items;
                            model.properties.Add("Results", p);

                            r.models.TryAdd("PageData_" + dataObjType.Name, model);
                        }
                    }
                    else if (returnType.Name.Equals("Page`1"))
                    {
                        var dataObjType = types[0];
                        AddTypeToProcessQueue(r, dataObjType, queue);
                        var paging = returnType.GetProperty("Paging");
                        if (paging != null)
                        {//add paging type manually
                            AddTypeToProcessQueue(r, paging.PropertyType, queue);
                        }
                        //Page_xxxxx

                        if (!r.models.ContainsKey("Page_" + dataObjType.Name))
                        {
                            var model = new ResourceApiModel();

                            model.id         = "Page_" + dataObjType.Name;
                            model.properties = new Dictionary <string, ResourceApiModelProperty>();

                            var p = new ResourceApiModelProperty();
                            p.type        = "Paging";
                            p.description = "Paging info";

                            model.properties.Add("Paging", p);

                            p             = new ResourceApiModelProperty();
                            p.type        = "Array";
                            p.description = "A page of data";
                            var items = new Dictionary <string, string>();
                            items.Add("$ref", dataObjType.Name);
                            p.items = items;
                            model.properties.Add("Records", p);
                            r.models.TryAdd("Page_" + dataObjType.Name, model);
                        }
                    }
                    else
                    {
                        var dataObjType = types[0];
                        AddTypeToProcessQueue(r, dataObjType, queue);
                    }
                }
                //process queue
                while (queue.Count > 0)
                {
                    var type = queue[0];
                    AddModelDataObject(r, queue[0], queue);
                    queue.Remove(type);
                }
            }
        }
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            ResourceApiOperation rApiOperation = new ResourceApiOperation()
            {
                httpMethod     = api.HttpMethod.ToString(),
                nickname       = docProvider.GetNickname(api.ActionDescriptor),
                responseClass  = TypeParser.Parse(docProvider.GetResponseClass(api.ActionDescriptor)),
                summary        = api.Documentation,
                notes          = docProvider.GetNotes(api.ActionDescriptor),
                parameters     = new List <ResourceApiOperationParameter>(),
                errorResponses = docProvider.GetErrorResponses(api)
            };

            return(rApiOperation);
        }
Exemple #25
0
        public static void TryToAddModels(ConcurrentDictionary <string, TypeInfo> models, Type type, XmlCommentDocumentationProvider docProvider, ConcurrentDictionary <string, string> typesToReturn = null, int level = 0)
        {
            var _type = type;

            if (type.IsArray)
            {
                _type = type.GetElementType();
            }
            else if (type.IsGenericType)
            {
                _type = type.GetGenericArguments().First();
            }

            string typeName = GetTypeName(_type);

            if (models.Any(m => m.Key == typeName))
            {
                return;
            }

            if (IsOutputable(_type))
            {
                var typeInfo = new TypeInfo {
                    id = typeName
                };
                if (!IgnoreTypes.Contains(_type.Name.ToLower()))
                {
                    typeInfo.description = docProvider.GetSummary(_type);
                }
                //Ignore properties for .net types
                if (!_type.Assembly.FullName.Contains("System") && !_type.Assembly.FullName.Contains("mscorlib"))
                {
                    var modelInfoDic = new Dictionary <string, PropInfo>();
                    foreach (var propertyInfo in _type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        if (propertyInfo.GetCustomAttributes(typeof(JsonIgnoreAttribute), false).FirstOrDefault() != null)
                        {
                            continue;
                        }

                        var propInfo = new PropInfo();

                        string      propName    = GetPropertyName(propertyInfo);
                        Type        propType    = docProvider.GetType(propertyInfo);
                        SwaggerType swaggerType = GetSwaggerType(propType);
                        propInfo.type     = swaggerType.Name;
                        propInfo.items    = swaggerType.Items;
                        propInfo.required = IsRequired(propertyInfo, docProvider);


                        if (!modelInfoDic.Keys.Contains(propName))
                        {
                            modelInfoDic.Add(propName, propInfo);
                        }

                        if (!IgnoreTypes.Contains(propInfo.type))
                        {
                            propInfo.description = docProvider.GetSummary(propertyInfo);
                            if (propertyInfo.PropertyType.IsEnum)
                            {
                                modelInfoDic[propName].@enum = propertyInfo.PropertyType.GetEnumNames();
                            }
                            //Don't go too deep
                            if (level < 10)
                            {
                                TryToAddModels(models, swaggerType.type, docProvider, typesToReturn, ++level);
                            }
                        }
                    }
                    typeInfo.properties = modelInfoDic;
                }
                if (_type.IsEnum)
                {
                    typeInfo.values = _type.GetEnumNames();
                }

                models.TryAdd(typeName, typeInfo);
            }
        }
Exemple #26
0
        /// <summary>
        /// Creates an api operation
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An api operation</returns>
        public static ResourceApiOperation CreateResourceApiOperation(ResourceListing r, ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            ResourceApiOperation rApiOperation = new ResourceApiOperation()
            {
                httpMethod    = api.HttpMethod.ToString(),
                nickname      = docProvider.GetNickname(api.ActionDescriptor),
                responseClass = docProvider.GetResponseClass(api.ActionDescriptor),
                summary       = docProvider.GetDocumentation(api.ActionDescriptor),
                notes         = docProvider.GetNotes(api.ActionDescriptor),
                parameters    = new List <ResourceApiOperationParameter>(),
            };

            if (string.IsNullOrEmpty(rApiOperation.notes) || rApiOperation.notes.Equals("No Documentation Found."))
            {
                rApiOperation.notes = rApiOperation.summary;
            }
            return(rApiOperation);
        }
Exemple #27
0
        private static bool IsRequired(PropertyInfo propertyInfo, XmlCommentDocumentationProvider docProvider)
        {
            if (propertyInfo.PropertyType.IsGenericType &&
                propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                return false;

            return docProvider.IsRequired(propertyInfo);
        }
Exemple #28
0
        /// <summary>
        /// Creates an operation parameter
        /// </summary>
        /// <param name="api">Description of the api via the ApiExplorer</param>
        /// <param name="param">Description of a parameter on an operation via the ApiExplorer</param>
        /// <param name="docProvider">Access to the XML docs written in code</param>
        /// <returns>An operation parameter</returns>
        public static ResourceApiOperationParameter CreateResourceApiOperationParameter(ResourceListing r, ApiDescription api, ApiParameterDescription param, XmlCommentDocumentationProvider docProvider)
        {
            string paramType = (param.Source.ToString().Equals(FROMURI)) ? QUERY : BODY;
            var    dataType  = param.ParameterDescriptor.ParameterType.Name;

            switch (dataType)
            {
            case "List`1":
                var dataObjType = param.ParameterDescriptor.ParameterType.GetGenericArguments()[0];
                dataType = string.Format("Array[{0}]", dataObjType.Name);
                break;

            case "Nullable`1":
                var dd = param.ParameterDescriptor.ParameterType.GetGenericArguments()[0];
                dataType = dd.Name;
                break;

            case "Dictionary`2":

                dataType = string.Format("Array[{0},{1}]", param.ParameterDescriptor.ParameterType.GetGenericArguments()[0].Name,
                                         param.ParameterDescriptor.ParameterType.GetGenericArguments()[1].Name);
                break;

            default:
                if (!IsExceptType(param.ParameterDescriptor.ParameterType))
                {
                    AddModelDataObject(r, param.ParameterDescriptor.ParameterType);
                }
                break;
            }
            ResourceApiOperationParameter parameter = new ResourceApiOperationParameter()
            {
                paramType   = (paramType == "query" && api.RelativePath.IndexOf("{" + param.Name + "}") > -1) ? PATH : paramType,
                name        = param.Name,
                description = param.Name.Equals("sessionKey") ? "Login session" : (string.IsNullOrWhiteSpace(param.Documentation) ? NODESCRIPTION : param.Documentation),
                dataType    = dataType,
                required    = docProvider.GetRequired(param.ParameterDescriptor)
            };

            return(parameter);
        }
Exemple #29
0
        public static List <ResourceApiOperationResponseMessage> GetResourceApiResponseMessage(ApiDescription api, XmlCommentDocumentationProvider docProvider)
        {
            List <ResourceApiOperationResponseMessage> ret = new List <ResourceApiOperationResponseMessage>();
            var elements = docProvider.GetResponseMessages(api.ActionDescriptor);

            if (elements != null)
            {
                while (elements.MoveNext())
                {
                    ret.Add(new ResourceApiOperationResponseMessage()
                    {
                        code    = elements.Current.GetAttribute("code", ""),
                        message = elements.Current.Value
                    });
                }
            }
            return(ret);
        }