private IEnumerable<PropertyDocumentation> CreatePropertyDocumentation(DtoDocumentationMetadata dtoDocumentationMetadata, String propertyPrefix) { if (propertyPrefix == null) { propertyPrefix = String.Empty; } IList<PropertyDocumentation> propertyDocumentation = new List<PropertyDocumentation>(); var propertyDescriptors = TypeDescriptor.GetProperties(dtoDocumentationMetadata.Type) .Cast<PropertyDescriptor>() .Where(pi => pi.PropertyType.GetCustomAttributes(true) .All(attribute => !(attribute is NonSerializedAttribute) && !(attribute is IgnoreDataMemberAttribute))) .Select(pi => pi) .ToList(); foreach (var propertyDescriptor in propertyDescriptors) { var documentedProperty = dtoDocumentationMetadata.PropertyDocumentationMetadata .SingleOrDefault( metadata => metadata.Property.Name.Equals(propertyDescriptor.Name) && metadata.Property.PropertyType.Equals(propertyDescriptor.PropertyType)); if (!TypeHelper.CanConvertFromString(propertyDescriptor.PropertyType) && _WebApiDocumentationMetadata.DtoDocumentation.ContainsKey(propertyDescriptor.PropertyType)) { propertyDocumentation.Add( new PropertyDocumentation( GetPropertyNamePrefix(propertyDescriptor, propertyPrefix), GetProperyTypeName(propertyDescriptor.PropertyType), _WebApiDocumentationMetadata.DtoDocumentation[propertyDescriptor.PropertyType].Summary)); propertyDocumentation.AddRange( CreatePropertyDocumentation( _WebApiDocumentationMetadata.DtoDocumentation[propertyDescriptor.PropertyType], String.Format("{0}{1}{2}", propertyPrefix, String.IsNullOrWhiteSpace(propertyPrefix) ? String.Empty : ".", propertyDescriptor.Name))); } else if (!TypeHelper.CanConvertFromString(propertyDescriptor.PropertyType) && GetEnumerableType(propertyDescriptor.PropertyType) != null && (propertyDescriptor.PropertyType.IsGenericType && _WebApiDocumentationMetadata.DtoDocumentation.ContainsKey(propertyDescriptor.PropertyType.GetGenericArguments().First()))) { var genericPropertyType = propertyDescriptor.PropertyType.GetGenericArguments().First(); propertyDocumentation.Add( new PropertyDocumentation( GetPropertyNamePrefix(propertyDescriptor, propertyPrefix), GetProperyTypeName(propertyDescriptor.PropertyType), _WebApiDocumentationMetadata.DtoDocumentation[genericPropertyType].Summary)); if (propertyPrefix.Contains(propertyDescriptor.Name) || genericPropertyType.Equals(dtoDocumentationMetadata.Type)) { continue; // Prevent circular dependencies. } propertyDocumentation.AddRange( CreatePropertyDocumentation( _WebApiDocumentationMetadata.DtoDocumentation[genericPropertyType], String.Format("{0}{1}{2}", propertyPrefix, String.IsNullOrWhiteSpace(propertyPrefix) ? String.Empty : ".", propertyDescriptor.Name))); } else { propertyDocumentation.Add( new PropertyDocumentation( GetPropertyNamePrefix(propertyDescriptor, propertyPrefix), GetProperyTypeName(propertyDescriptor.PropertyType), documentedProperty == null ? String.Empty : documentedProperty.Description)); } } return propertyDocumentation; }
private Object CreateResponseContentExample(DtoDocumentationMetadata dtoDocumentationMetadata) { // Create an example DTO based off AutoFixture / ObjectHydrator conventions to be used as reference if properties aren't documented. var exampleObject = CreateInstanceOfType(dtoDocumentationMetadata.Type); IDictionary<String, Object> responseExample = new ExpandoObject(); var propertyDescriptors = TypeDescriptor.GetProperties(dtoDocumentationMetadata.Type); var dtoProperties = dtoDocumentationMetadata.Type .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(pi => pi.GetCustomAttributes(true) .All( attribute => !(attribute is NonSerializedAttribute) && !(attribute is IgnoreDataMemberAttribute))) .Select(pi => propertyDescriptors[pi.Name]); foreach (var propertyDescriptor in dtoProperties) { if (!TypeHelper.CanConvertFromString(propertyDescriptor.PropertyType) && _WebApiDocumentationMetadata.DtoDocumentation.ContainsKey(propertyDescriptor.PropertyType)) { responseExample[propertyDescriptor.Name] = CreateResponseContentExample(_WebApiDocumentationMetadata.DtoDocumentation[propertyDescriptor.PropertyType]); } else { responseExample[propertyDescriptor.Name] = propertyDescriptor.GetValue(exampleObject); } } return responseExample; }
private Object CreateRequestBodyExample(HttpActionDescriptor httpActionDescriptor, DtoDocumentationMetadata dtoDocumentationMetadata) { // Create an example DTO based off AutoFixture / ObjectHydrator conventions to be used as reference if properties aren't documented. var exampleObject = CreateInstanceOfType(dtoDocumentationMetadata.Type); IDictionary<String, Object> requestBodyExample = new ExpandoObject(); foreach (DtoPropertyDocumentationMetadata dtoProperty in dtoDocumentationMetadata.PropertyDocumentationMetadata) { if (!TypeHelper.CanConvertFromString(dtoProperty.Property.PropertyType) && _WebApiDocumentationMetadata.DtoDocumentation.ContainsKey(dtoProperty.Property.PropertyType)) { requestBodyExample[dtoProperty.Property.Name] = CreateRequestBodyExample(httpActionDescriptor, _WebApiDocumentationMetadata.DtoDocumentation[dtoProperty.Property.PropertyType]); } else if (!httpActionDescriptor.SupportedHttpMethods.Intersect(dtoProperty.ExcludedMethods ?? Enumerable.Empty<HttpMethod>()).Any()) { if (_WebApiDocumentationMetadata.Settings .RequestBuilderConventions .Any(c => !c.IncludeProperty( httpActionDescriptor.SupportedHttpMethods, dtoDocumentationMetadata.Type.GetProperty(dtoProperty.Property.Name), dtoDocumentationMetadata.Type))) { continue; } var propertyDocumentationMetadata = dtoDocumentationMetadata.PropertyDocumentationMetadata .SingleOrDefault(pdm => pdm.Property.Equals(dtoProperty.Property) && pdm.ExampleValue != null); if (propertyDocumentationMetadata != null) { requestBodyExample[dtoProperty.Property.Name] = propertyDocumentationMetadata.ExampleValue; } else { requestBodyExample[dtoProperty.Property.Name] = dtoProperty.Property.GetValue(exampleObject); } } } return requestBodyExample; }