Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting XML comments from multiple .csproj files to populate in Swagger UI

I know that similar questions have been asked here but I'm truly at a loss. I currently have around 5ish .csproj files as a part of a web application that all contain XML comments. Proj1 is the only one that is currently populating those comments into the swagger documentation. I can see that .xml files are being created with the correct information in the file paths (ex file created at proj3/bin/Debug/net6.0/proj3.xml). But, as stated, the comments from proj1 are the only ones showing up in Swagger.

I currently have a Directory.Build.props with the following lines:

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
        <GenerateDocumentationFile>true</GenerateDocumentationFile>
        <NoWarn>$(NoWarn);1570;1572;1573;1587;1591;1701;1702;1705;1591</NoWarn>
     </PropertyGroup>

and the following swagger configuration in my startup:

  //  configure swagger API documentation
    builder.Services.AddSwaggerGen(config => {
       config.SwaggerDoc(appVersion, new OpenApiInfo {
           Title = "Proj1 API",
           Version = appVersion,
           Description = "REST API for control of Proj1 data"
       });
       config.SchemaFilter<ResourceSchemaFilter>();
       config.OrderActionsBy(a => $"{a.RelativePath}_{a.HttpMethod}");
       config.CustomSchemaIds(x => x.FullName);

       //  add the xml comments to the swagger generated json
       var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
       var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
       config.IncludeXmlComments(xmlPath);
    });

    //  build the application with all services

    var app = builder.Build();

    if (app.Environment.IsDevelopment()) {

       //  enable swagger documentation
       var swaggerRoute = "api-docs";
       app.UseSwagger(c => {
           c.RouteTemplate = $"{swaggerRoute}/{{documentName}}/swagger.json";
       });
       app.UseSwaggerUI(c => {
           c.SwaggerEndpoint($"/{swaggerRoute}/{appVersion}/swagger.json", $"Proj1 API {appVersion})");
           c.RoutePrefix = swaggerRoute;
       });

I tried adding a $(OutputPath)$(AssemblyName).xml line as another property group as well as trying it as a line under the GenerateDocumentationFile line in the original project group. I've also tried adding the true blurb individually to each .csproj file. Each time, I get the Xml comments from files listed in only 1 of the .csproj files. Any help would be greatly appreciated! Does doing mental laps count as cardio?

like image 284
Kaila Williams Avatar asked Nov 18 '25 11:11

Kaila Williams


2 Answers

You can find all XML files in your solution using below 2 lines:

List<string> xmlFiles = Directory.GetFiles(AppContext.BaseDirectory,"*.xml",SearchOption.TopDirectoryOnly).ToList();
xmlFiles.ForEach(xmlFile => swaggerGenOptions.IncludeXmlComments(xmlFile)); 

make sure to change the patter used in search (*.xml) if you have XML files rather than those for "documentation comments".

like image 144
Ahmed Ashour Avatar answered Nov 20 '25 02:11

Ahmed Ashour


For me, the best way is to add comments from assemblies you explicitly choose:

First, you must enable the generation of xml comments for all assemblies you want to add to your Swagger domumentation (in Visual Studio enable: Project / Properties / Build / Output / Generate a file containing API documentation).

Then, add the produced xml files to your startup code this way:

public class Startup
{
    static string XmlFileName(Type type) => type.GetTypeInfo().Module.Name.Replace(".dll", ".xml").Replace(".exe", ".xml");

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
        {
            // add xml comments from Controllers
            c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, XmlFileName(typeof(Program))));
            // add xml comments from the Contract (i.e. DTOs)
            c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, XmlFileName(typeof(AppUserDetailDto))));
            // etc...
        }
    }    
}
like image 36
Daniel Smolka Avatar answered Nov 20 '25 02:11

Daniel Smolka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!