Using FluentValidation with WebAPI, I am attempting to show the rules that are implemented on a property.
I am using the Microsoft.AspNet.WebApi.HelpPage assemblies that will generate the help pages for my API. I would like to be able to enumerate the validation rules so I can display the attributes like required and the length on my help pages.
Previously, I would do this for a custom attribute with something like the following:
-- namespace MyAPI.Areas.HelpPage.ModelDescriptions
private readonly IDictionary<Type, Func<object, string>> AnnotationTextGenerator =
new Dictionary<Type, Func<object, string>>
{
{ typeof(MyAttribute), a => "My Attribute Documentation" }
};
This would add the text required in the additional information section of the help page. In the event of using FluentValidation, the required type is no longer set. It is now something like RuleFor(x => x.MyProperty).NotEmpty();
If helpful, the code that is documenting the annotations is below:
-- namespace MyAPI.Areas.HelpPage.ModelDescriptions
/// <summary> Generates the annotations. </summary>
/// <param name="property"> The property. </param>
/// <param name="propertyModel"> The property model. </param>
private void GenerateAnnotations(MemberInfo property, ParameterDescription propertyModel)
{
var annotations = new List<ParameterAnnotation>();
var attributes = property.GetCustomAttributes();
foreach (var attribute in attributes)
{
Func<object, string> textGenerator;
if (AnnotationTextGenerator.TryGetValue(attribute.GetType(), out textGenerator))
{
annotations.Add(
new ParameterAnnotation
{
AnnotationAttribute = attribute,
Documentation = textGenerator(attribute)
});
}
}
// Rearrange the annotations
annotations.Sort(
(x, y) =>
{
// Special-case RequiredAttribute so that it shows up on top
if (x.AnnotationAttribute is RequiredAttribute)
{
return -1;
}
if (y.AnnotationAttribute is RequiredAttribute)
{
return 1;
}
// Sort the rest based on alphabetic order of the documentation
return String.Compare(x.Documentation, y.Documentation, StringComparison.OrdinalIgnoreCase);
});
foreach (var annotation in annotations)
{
propertyModel.Annotations.Add(annotation);
}
}
When calling this GenerateAnnotations routine I would like to add the logic that will look at the property and get all the fluent attributes assigned and add the text.
Maybe somehow use the FluentValidation.Internal.PropertyRules to elegantly enumerate the attributes?