Created
January 31, 2022 10:38
-
-
Save magnusbakken/d3329b65ac5d9493bf112d6b8a88705b to your computer and use it in GitHub Desktop.
A custom Swashbuckle schema filter that adds remarks to schema descriptions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Xml.XPath; | |
using Microsoft.OpenApi.Models; | |
namespace Swashbuckle.AspNetCore.SwaggerGen; | |
// This is a slightly modified version of the built-in XmlCommentsSchemaFilter. | |
// Currently our only modifications are that we append the contents of the <remarks> section to the description for each schema item. | |
public class CustomXmlCommentsSchemaFilter : ISchemaFilter | |
{ | |
private readonly XPathNavigator _xmlNavigator; | |
public CustomXmlCommentsSchemaFilter(XPathDocument xmlDoc) | |
{ | |
_xmlNavigator = xmlDoc.CreateNavigator(); | |
} | |
public void Apply(OpenApiSchema schema, SchemaFilterContext context) | |
{ | |
ApplyTypeTags(schema, context.Type); | |
if (context.MemberInfo != null) | |
{ | |
ApplyMemberTags(schema, context); | |
} | |
} | |
private void ApplyTypeTags(OpenApiSchema schema, Type type) | |
{ | |
var typeMemberName = XmlCommentsNodeNameHelper.GetMemberNameForType(type); | |
var typeNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{typeMemberName}']"); | |
if (typeNode == null) | |
return; | |
var typeSummaryNode = typeNode.SelectSingleNode("summary"); | |
if (typeSummaryNode != null) | |
schema.Description = XmlCommentsTextHelper.Humanize(typeSummaryNode.InnerXml); | |
// This is the part we've added. Remarks are appended to the description with a couple of linebreaks in between. | |
var typeRemarksNode = typeNode.SelectSingleNode("remarks"); | |
if (typeRemarksNode != null) | |
schema.Description = $"{schema.Description}\r\n\r\n{XmlCommentsTextHelper.Humanize(typeRemarksNode.InnerXml)}"; | |
} | |
private void ApplyMemberTags(OpenApiSchema schema, SchemaFilterContext context) | |
{ | |
var fieldOrPropertyMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(context.MemberInfo); | |
var fieldOrPropertyNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{fieldOrPropertyMemberName}']"); | |
if (fieldOrPropertyNode == null) return; | |
var summaryNode = fieldOrPropertyNode.SelectSingleNode("summary"); | |
if (summaryNode != null) | |
schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); | |
// This is the part we've added. Remarks are appended to the description with a couple of linebreaks in between. | |
var remarksNode = fieldOrPropertyNode.SelectSingleNode("remarks"); | |
if (remarksNode != null) | |
schema.Description = $"{schema.Description}\r\n\r\n{XmlCommentsTextHelper.Humanize(remarksNode.InnerXml)}"; | |
var exampleNode = fieldOrPropertyNode.SelectSingleNode("example"); | |
if (exampleNode != null) | |
{ | |
var exampleAsJson = (schema.ResolveType(context.SchemaRepository) == "string") | |
? $"\"{exampleNode.InnerXml}\"" | |
: exampleNode.InnerXml; | |
schema.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment