private static void ParseModel(IDictionary <string, SwaggerModel> models, Type modelType) { if (IsSwaggerScalarType(modelType)) { return; } var modelId = modelType.Name; if (models.ContainsKey(modelId)) { return; } var model = new SwaggerModel { Id = modelId, Properties = new Dictionary <string, ModelProperty>() }; models[model.Id] = model; var hasDataContract = modelType.HasAttr <DataContractAttribute>(); foreach (var prop in modelType.GetProperties()) { DataMemberAttribute dataMemberAttribute = null; if (hasDataContract) { dataMemberAttribute = prop.GetDataMember(); if (dataMemberAttribute == null) { continue; } } else if (prop.IsDefined(typeof(IgnoreDataMemberAttribute), true)) { continue; } var allApiDocAttributes = prop .GetCustomAttributes(typeof(ApiMemberAttribute), true) .OfType <ApiMemberAttribute>() .Where(attr => prop.Name.Equals(attr.Name, StringComparison.InvariantCultureIgnoreCase)) .ToList(); var apiDoc = allApiDocAttributes.FirstOrDefault(attr => attr.ParameterType == "body"); if (allApiDocAttributes.Any() && apiDoc == null) { continue; } var propertyType = prop.PropertyType; var isRequired = dataMemberAttribute == null ? !IsNullable(propertyType) : dataMemberAttribute.IsRequired; var modelProp = new ModelProperty { Type = GetSwaggerTypeName(propertyType), Required = isRequired }; if (IsListType(propertyType)) { modelProp.Type = SwaggerType.Array; var listItemType = GetListElementType(propertyType); modelProp.Items = new Dictionary <string, string> { { IsSwaggerScalarType(listItemType) ? "type" : "$ref", GetSwaggerTypeName(listItemType) } }; ParseModel(models, listItemType); } else if ((Nullable.GetUnderlyingType(propertyType) ?? propertyType).IsEnum) { var enumType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; if (enumType.IsNumericType()) { var underlyingType = Enum.GetUnderlyingType(enumType); modelProp.Type = GetSwaggerTypeName(underlyingType); modelProp.AllowableValues = new ParameterAllowableValues { Values = GetNumericValues(enumType, underlyingType).ToArray(), ValueType = "LIST" }; } else { modelProp.Type = SwaggerType.String; modelProp.AllowableValues = new ParameterAllowableValues { Values = Enum.GetNames(enumType), ValueType = "LIST" }; } } else { ParseModel(models, propertyType); } var descriptionAttr = prop.GetCustomAttributes(typeof(DescriptionAttribute), true).OfType <DescriptionAttribute>().FirstOrDefault(); if (descriptionAttr != null) { modelProp.Description = descriptionAttr.Description; } if (apiDoc != null) { modelProp.Description = apiDoc.Description; } var allowableValues = prop.GetCustomAttributes(typeof(ApiAllowableValuesAttribute), true).OfType <ApiAllowableValuesAttribute>().FirstOrDefault(); if (allowableValues != null) { modelProp.AllowableValues = GetAllowableValue(allowableValues); } model.Properties[GetModelPropertyName(prop, dataMemberAttribute)] = modelProp; } }
private static void ParseModel(IDictionary<string, SwaggerModel> models, Type modelType) { if (IsSwaggerScalarType(modelType)) return; var modelId = modelType.Name; if (models.ContainsKey(modelId)) return; var model = new SwaggerModel { Id = modelId, Properties = new Dictionary<string, ModelProperty>() }; models[model.Id] = model; var hasDataContract = modelType.HasAttr<DataContractAttribute>(); foreach (var prop in modelType.GetProperties()) { DataMemberAttribute dataMemberAttribute = null; if (hasDataContract) { dataMemberAttribute = prop.GetDataMember(); if (dataMemberAttribute == null) { continue; } } else if (prop.IsDefined(typeof(IgnoreDataMemberAttribute), true)) { continue; } var allApiDocAttributes = prop .GetCustomAttributes(typeof(ApiMemberAttribute), true) .OfType<ApiMemberAttribute>() .Where(attr => prop.Name.Equals(attr.Name, StringComparison.InvariantCultureIgnoreCase)) .ToList(); var apiDoc = allApiDocAttributes.FirstOrDefault(attr => attr.ParameterType == "body"); if (allApiDocAttributes.Any() && apiDoc == null) continue; var propertyType = prop.PropertyType; var isRequired = dataMemberAttribute == null ? !IsNullable(propertyType) : dataMemberAttribute.IsRequired; var modelProp = new ModelProperty { Type = GetSwaggerTypeName(propertyType), Required = isRequired }; if (IsListType(propertyType)) { modelProp.Type = SwaggerType.Array; var listItemType = GetListElementType(propertyType); modelProp.Items = new Dictionary<string, string> { { IsSwaggerScalarType(listItemType) ? "type" : "$ref", GetSwaggerTypeName(listItemType) } }; ParseModel(models, listItemType); } else if ((Nullable.GetUnderlyingType(propertyType) ?? propertyType).IsEnum) { var enumType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; if (enumType.IsNumericType()) { var underlyingType = Enum.GetUnderlyingType(enumType); modelProp.Type = GetSwaggerTypeName(underlyingType); modelProp.AllowableValues = new ParameterAllowableValues { Values = GetNumericValues(enumType, underlyingType).ToArray(), ValueType = "LIST" }; } else { modelProp.Type = SwaggerType.String; modelProp.AllowableValues = new ParameterAllowableValues { Values = Enum.GetNames(enumType), ValueType = "LIST" }; } } else { ParseModel(models, propertyType); } var descriptionAttr = prop.GetCustomAttributes(typeof(DescriptionAttribute), true).OfType<DescriptionAttribute>().FirstOrDefault(); if (descriptionAttr != null) modelProp.Description = descriptionAttr.Description; if (apiDoc != null) modelProp.Description = apiDoc.Description; var allowableValues = prop.GetCustomAttributes(typeof(ApiAllowableValuesAttribute), true).OfType<ApiAllowableValuesAttribute>().FirstOrDefault(); if (allowableValues != null) modelProp.AllowableValues = GetAllowableValue(allowableValues); model.Properties[GetModelPropertyName(prop, dataMemberAttribute)] = modelProp; } }