private static DefinitionProperty ProcessProperty(PropertyInfo propertyInfo, IList <string> hiddenTags, Stack <Type> typesStack) { if (propertyInfo.GetCustomAttribute <SwaggerWcfHiddenAttribute>() != null || propertyInfo.GetCustomAttributes <SwaggerWcfTagAttribute>() .Select(t => t.TagName) .Any(hiddenTags.Contains)) { return(null); } TypeFormat typeFormat = Helpers.MapSwaggerType(propertyInfo.PropertyType, null); DefinitionProperty prop = new DefinitionProperty { Title = propertyInfo.Name }; DataMemberAttribute dataMemberAttribute = propertyInfo.GetCustomAttribute <DataMemberAttribute>(); var useDataMember = SwaggerWcfEndpoint.NotUseDataMemberAttributeExceptedType.Contains(propertyInfo.ReflectedType) || !SwaggerWcfEndpoint.NotUseDataMemberAttribute; if (useDataMember && dataMemberAttribute != null) { if (!string.IsNullOrEmpty(dataMemberAttribute.Name)) { prop.Title = dataMemberAttribute.Name; } prop.Required = dataMemberAttribute.IsRequired; } // Special case - if it came out required, but we unwrapped a null-able type, // then it's necessarily not required. Ideally this would only set the default, // but we can't tell the difference between an explicit declaration of // IsRequired =false on the DataMember attribute and no declaration at all. if (prop.Required && propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { prop.Required = false; } DescriptionAttribute descriptionAttribute = propertyInfo.GetCustomAttribute <DescriptionAttribute>(); if (descriptionAttribute != null) { prop.Description = descriptionAttribute.Description; } SwaggerWcfRegexAttribute regexAttr = propertyInfo.GetCustomAttribute <SwaggerWcfRegexAttribute>(); if (regexAttr != null) { prop.Pattern = regexAttr.Regex; } prop.TypeFormat = typeFormat; if (prop.TypeFormat.Type == ParameterType.Object) { typesStack.Push(propertyInfo.PropertyType); prop.Ref = propertyInfo.PropertyType.GetModelName(); return(prop); } if (prop.TypeFormat.Type == ParameterType.Array) { Type subType = DefinitionsBuilder.GetEnumerableType(propertyInfo.PropertyType); if (subType != null) { TypeFormat subTypeFormat = Helpers.MapSwaggerType(subType, null); if (subType == typeof(byte) || subType == typeof(sbyte)) { prop.TypeFormat = subTypeFormat; } else { if (subTypeFormat.Type == ParameterType.Object) { typesStack.Push(subType); } prop.Items = new ParameterItems { TypeFormat = subTypeFormat }; } } } if (prop.TypeFormat.Format == "enum") { prop.Enum = new Dictionary <string, int>(); Type propType = propertyInfo.PropertyType; if (propType.IsGenericType && (propType.GetGenericTypeDefinition() == typeof(Nullable <>) || propType.GetGenericTypeDefinition() == typeof(List <>))) { propType = propType.GetEnumerableType(); } List <string> listOfEnumNames = propType.GetEnumNames().ToList(); foreach (string enumName in listOfEnumNames) { var enumMemberItem = Enum.Parse(propType, enumName, true); int enumMemberValue = DefinitionsBuilder.GetEnumMemberValue(propType, enumName); prop.Enum.Add(enumName, enumMemberValue); } } // Apply any options set in a [SwaggerWcfProperty] DefinitionsBuilder.ApplyAttributeOptions(propertyInfo, prop); return(prop); }