Is there an alternate way to add Swagger comments?

63 views Asked by At

I would like to get method comments that are in a manager class that is directly called by a controller to show up in Swagger UI. The only way I know of to do that is to copy and paste the comments from the manager class to the controller. Previously, there was a nu-get package that would make this transfer on compliation. I am no longer able to find it, and I remember it not working well anyway.

Traditional Method:    
Controller method comments => SwaggerUI

Desired Method:
MangerClass method comments => SwaggerUI

enter image description here

XML Comments: https://learn.microsoft.com/en-us/visualstudio/ide/reference/generate-xml-documentation-comments?view=vs-2022

2

There are 2 answers

0
Ruikai Feng On BEST ANSWER

Make sure you've called this line in your project file:

<PropertyGroup>  
 <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

then it would generate the xml file:{Assembly.GetExecutingAssembly().GetName().Name}.xml

Two possible solution :

Solution 1:

modify the xml document generated and configure swagger to use the modified xml document to generate UI

In program.cs:

var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
XmlDocument doc = new XmlDocument();
doc.Load(Path.Combine(AppContext.BaseDirectory, xmlFilename));
XmlNodeList nodes = doc.SelectNodes("//members/member");
//modify the  nodes based on your requirement,you have to write the codes yourself
nodes[0].Attributes[0].Value = String.Format("M:{0}", "YourAssemblyName.Controllers.WeatherForecastController.Get");
var targetpath = ".....";
doc.Save(targetpath);
builder.Services.AddSwaggerGen(options =>
{
    options.IncludeXmlComments(targetpath);        
});

Result:

enter image description here

Solution 2:

Read key-value pairs from the xml document with C# codes

Create an operation filter:

public class MyParameterFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        //assingn the key value pairs you read from xml
        operation.Summary = "Summary";
    }
}

apply the filter:

builder.Services.AddSwaggerGen(options =>
{
    options.OperationFilter<MyParameterFilter>();
});

Result:

enter image description here

0
Nelson Nyland On

Ruikai's answer helped me get to this solution:

public class XmlUtil
{
    public static void CopyComments(string filePath, string origin, string destination)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(filePath);
        XmlNodeList nodes = doc.GetElementsByTagName("member");
        var appendNodes = new List<XmlElement>();
        foreach (XmlNode node in nodes)
        {
            if (node.OuterXml.Contains($"{origin}."))
            {
                XmlElement memberEl = doc.CreateElement("member");
                XmlAttribute nameAtt = doc.CreateAttribute("name");
                string name = node.OuterXml.Substring(node.OuterXml.IndexOf("\"") + 1);
                name = name.Substring(0, name.IndexOf("\""));
                nameAtt.Value = name.Replace(origin, destination);
                memberEl.SetAttribute("name", nameAtt.Value);
                XmlElement summaryEl = doc.CreateElement("summary");
                XmlText text = doc.CreateTextNode(node.InnerText);
                summaryEl.AppendChild(text);
                memberEl.AppendChild(summaryEl);
                appendNodes.Add(memberEl);
            }
        }
        XmlNode root = doc.SelectSingleNode("//members");
        foreach (var node in appendNodes)
        {
            root.AppendChild(node);
        }
        doc.Save(filePath);
    }
}