unchase / Unchase.Swashbuckle.AspNetCore.Extensions

:hammer: A library contains a bunch of extensions (filters) for Swashbuckle.AspNetCore.
https://www.nuget.org/packages/Unchase.Swashbuckle.AspNetCore.Extensions
Apache License 2.0
115 stars 16 forks source link

IncludeXmlCommentsFromInheritDocs is broken in Swashbuckle.AspNetCore 6.8.0 #38

Open alser opened 1 week ago

alser commented 1 week ago
// xml comments file generated by c# compiler, no matter the contents (with or w/o inheritdocs)
const string xmlFilePath = "path/to/MyAssembly.xml";

services.AddSwaggerGen(options =>
{
    options.IncludeXmlComments(xmlFilePath);
    options.IncludeXmlCommentsFromInheritDocs();
});

Call to IncludeXmlCommentsFromInheritDocs fails with the exception below.

System.ArgumentNullException: Value cannot be null. (Parameter 'source')
   at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found)
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Unchase.Swashbuckle.AspNetCore.Extensions.Extensions.SwaggerGenOptionsExtensions.<>c.<IncludeXmlCommentsFromInheritDocs>b__7_1(FilterDescriptor x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Unchase.Swashbuckle.AspNetCore.Extensions.Extensions.SwaggerGenOptionsExtensions.IncludeXmlCommentsFromInheritDocs(SwaggerGenOptions swaggerGenOptions, Boolean includeRemarks, Type[] excludedTypes)

Same behavior if supplied XPathDocument:

options.IncludeXmlComments(() => new XPathDocument(new StringReader(File.ReadAllText(xmlFilePath))));

In Swashbuckle.AspNetCore sources method IncludeXmlComments results in calling to:

swaggerGenOptions.AddSchemaFilterInstance(new XmlCommentsSchemaFilter(xmlDocMembers));

which in turn does this:

swaggerGenOptions.SchemaFilterDescriptors.Add(new FilterDescriptor
{
    Type = typeof(TFilter),
    FilterInstance = filterInstance
});

therefore creating FilterDescriptor with Arguments = null.

Method IncludeXmlCommentsFromInheritDocs in this repo starts with:

var documents = swaggerGenOptions.SchemaFilterDescriptors.Where(x => x.Type == typeof(XmlCommentsSchemaFilter))
    .Select(x => x.Arguments.Single())
    .Cast<XPathDocument>()
    .ToList();

expecting to see single argument of type XPathDocument, but throwing ANE

sprudel79 commented 1 week ago

Same issue on my side in this call of method IncludeXmlCommentsFromInheritDocs:

List<XPathDocument> list = (from x in swaggerGenOptions.SchemaFilterDescriptors
                                    where x.Type == typeof(XmlCommentsSchemaFilter)
                                    select x.Arguments.Single()).Cast<XPathDocument>().ToList();

It's working with Swashbuckle 6.7.3, the question of course is, if it's a bug in that library or my bad understanding of the required setup. I have compared the swaggerGenOptions.SchemaFilterDescriptors content when using the 6.7.3 version and for the types XmlCommentsSchemaFilter I can always see a populated Arguments property.

alser commented 1 week ago

It's working in Swashbuckle 6.7.3 for me too, and same code in my app was working since at least 6.5.0 with the same version of Unchase.Swashbuckle.AspNetCore.Extensions 2.7.1

alser commented 1 week ago

I've reported this issue to Swashbuckle repo, to see if it's intended or not from their side https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/3081