예제 #1
0
        private static void AddModelDataObject(ResourceListing r, Type type, List <Type> queue)
        {
            if (!r.models.ContainsKey(type.Name))
            {
                var model = new ResourceApiModel();
                model.id         = type.Name;
                model.properties = new Dictionary <string, ResourceApiModelProperty>();
                foreach (var pi in type.GetProperties())
                {
                    var ignore = pi.GetCustomAttribute <System.Runtime.Serialization.IgnoreDataMemberAttribute>();
                    if (ignore != null)
                    {
                        continue;
                    }
                    var p = new ResourceApiModelProperty();
                    switch (pi.PropertyType.Name)
                    {
                    case "List`1":
                        var dataObjType = pi.PropertyType.GetGenericArguments()[0];
                        AddTypeToProcessQueue(r, dataObjType, queue);
                        p.type = "Array";
                        var items = new Dictionary <string, string>();
                        items.Add("$ref", dataObjType.Name);
                        p.items = items;
                        break;

                    case "Nullable`1":
                        var dd = pi.PropertyType.GetGenericArguments()[0];
                        p.type = dd.Name;
                        AddTypeToProcessQueue(r, dd, queue);
                        break;

                    case "Dictionary`2":
                        p.type = string.Format("Array[{0},{1}]"
                                               , pi.PropertyType.GetGenericArguments()[0].Name
                                               , pi.PropertyType.GetGenericArguments()[1].Name);
                        break;

                    default:
                        p.type = pi.PropertyType.Name;
                        AddTypeToProcessQueue(r, pi.PropertyType, queue);
                        break;
                    }

                    //get description from xml
                    p.description = GetDocumentation(pi);
                    if (string.IsNullOrWhiteSpace(p.description))
                    {
                        p.description = NODESCRIPTION;
                    }
                    if (!model.properties.ContainsKey(pi.Name))
                    {
                        model.properties.Add(pi.Name, p);
                    }
                    //check if this is a nested data obj type, put into queue if yes
                }

                r.models.TryAdd(type.Name, model);
            }
        }
예제 #2
0
        private static ResourceApiModel AddModelApiResponse(ResourceListing r, string targetTypeName)
        {
            if (!r.models.ContainsKey(targetTypeName))
            {
                var model = new ResourceApiModel();
                model.id         = targetTypeName;
                model.properties = new Dictionary <string, ResourceApiModelProperty>();
                var p = new ResourceApiModelProperty();
                p.type        = "bool";
                p.description = "Indicates whether the API call is success or not";
                model.properties.Add("Success", p);

                p             = new ResourceApiModelProperty();
                p.type        = "string";
                p.description = "Additional message for API result";
                model.properties.Add("Message", p);

                p             = new ResourceApiModelProperty();
                p.type        = "Exception";
                p.description = "In case catch an exception";
                model.properties.Add("Exception", p);


                r.models.TryAdd(targetTypeName, model);
                return(model);
            }
            else
            {
                return(null);
            }
        }
예제 #3
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);
                }
            }
        }