diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8a5ec97..89f7cc9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,11 @@
These are the changes to each version that has been released on the [nuget](https://www.nuget.org/packages/Unchase.Swashbuckle.AspNetCore.Extensions/).
+## v2.5.0 `2020-10-15`
+
+- [x] Fix some bugs in `IncludeXmlCommentsWithRemarks` option
+- [x] Add `IncludeXmlCommentsFromInheritDocs` option to add xml comments from inheritdocs (from summary and remarks) into the swagger documentation
+
## v2.4.1 `2020-10-13`
- [x] Add `params Type[]` parameters to `IncludeXmlCommentsWithRemarks` option to exclude remarks for concrete types
diff --git a/README.md b/README.md
index 14567cf..1670ce3 100644
--- a/README.md
+++ b/README.md
@@ -101,6 +101,10 @@ public void ConfigureServices(IServiceCollection services)
// use it if you want to hide Paths and Definitions from OpenApi documentation correctly
options.UseAllOfToExtendReferenceSchemas();
+ // if you want to add xml comments from inheritdocs (from summary and remarks) into the swagger documentation, add:
+ // you can exclude remarks for concrete types
+ options.IncludeXmlCommentsFromInheritDocs(includeRemarks: true, excludedTypes: typeof(string));
+
// if you want to add xml comments from summary and remarks into the swagger documentation, first of all add:
// you can exclude remarks for concrete types
var xmlFilePath = Path.Combine(AppContext.BaseDirectory, "WebApi3.1-Swashbuckle.xml");
@@ -352,6 +356,29 @@ public void ConfigureServices(IServiceCollection services)
}
```
+7. **Add xml comments from <inheritdoc/> (from summary and remarks) into the swagger documentation**:
+
+- Since [v2.5.0](https://github.com/unchase/Unchase.Swashbuckle.AspNetCore.Extensions/releases/tag/v2.5.0) in the _ConfigureServices_ method of _Startup.cs_, inside your `AddSwaggerGen` call, add `IncludeXmlCommentsFromInheritDocs` option:
+
+```csharp
+// This method gets called by the runtime. Use this method to add services to the container.
+public void ConfigureServices(IServiceCollection services)
+{
+ ...
+
+ services.AddSwaggerGen(options =>
+ {
+ ...
+
+ // add xml comments from inheritdocs (from summary and remarks) into the swagger documentation, add:
+ // with excluding concrete types
+ options.IncludeXmlCommentsFromInheritDocs(includeRemarks: true, excludedTypes: typeof(string));
+
+ ...
+ });
+}
+```
+
## Builds status
|Status|Value|
@@ -600,6 +627,83 @@ public enum SecondInnerEnum
}
```
+### Add xml comments from <inheritdoc/> (from summary and remarks) into the swagger documentation
+
+![Add xml comments from ingeritdoc](assets/addXmlCommentsFromInheritdoc.png)
+
+For code:
+
+```csharp
+///
+public class InheritDocClass : IInheritDocClass
+{
+ ///
+ public string Name { get; set; }
+
+ ///
+ public string Common { get; set; }
+
+ ///
+ public InheritEnum InheritEnum { get; set; }
+}
+
+///
+/// InheritDocClass - inheritdoc
+///
+///
+/// InheritDocClass remarks - inheritdoc
+///
+public interface IInheritDocClass : IInheritDocCommon
+{
+ ///
+ /// Name - inheritdoc
+ ///
+ ///
+ /// Name remarks - inheritdoc
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// IInheritDocCommon interface
+///
+///
+/// IInheritDocCommon interface remarks
+///
+public interface IInheritDocCommon
+{
+ ///
+ /// Common - inheritdoc (inner)
+ ///
+ ///
+ /// Common remarks - inheritdoc (inner)
+ ///
+ public string Common { get; set; }
+
+ ///
+ /// InheritEnum - inheritdoc (inner)
+ ///
+ public InheritEnum InheritEnum { get; set; }
+}
+
+///
+/// Inherit enum - enum
+///
+///
+/// Inherit enum remarks - enum
+///
+public enum InheritEnum
+{
+ ///
+ /// Inherit enum Value
+ ///
+ ///
+ /// Inherit enum Value remarks
+ ///
+ Value = 0
+}
+```
+
## HowTos
- [ ] Add HowTos in a future
diff --git a/Unchase.Swashbuckle.AspNetCore.Extensions.sln b/Unchase.Swashbuckle.AspNetCore.Extensions.sln
index 151f138..0112527 100644
--- a/Unchase.Swashbuckle.AspNetCore.Extensions.sln
+++ b/Unchase.Swashbuckle.AspNetCore.Extensions.sln
@@ -10,6 +10,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{145A03BF-E60E-41F6-BD89-457F940F6C9B}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
+ assets\addXmlCommentsFromInheritdoc.png = assets\addXmlCommentsFromInheritdoc.png
assets\addXmlCommentsFromSummaryAndRemarks.png = assets\addXmlCommentsFromSummaryAndRemarks.png
assets\appendActionCountIntoSwaggerTag.png = assets\appendActionCountIntoSwaggerTag.png
appveyor.yml = appveyor.yml
diff --git a/appveyor.yml b/appveyor.yml
index 53ac2d4..c784d07 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 2.4.{build}
+version: 2.5.{build}
pull_requests:
do_not_increment_build_number: true
skip_tags: true
diff --git a/assets/addXmlCommentsFromInheritdoc.png b/assets/addXmlCommentsFromInheritdoc.png
new file mode 100644
index 0000000..a723df3
Binary files /dev/null and b/assets/addXmlCommentsFromInheritdoc.png differ
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Extensions/SwaggerGenOptionsExtensions.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Extensions/SwaggerGenOptionsExtensions.cs
index d1ca0dc..d414c7c 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Extensions/SwaggerGenOptionsExtensions.cs
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Extensions/SwaggerGenOptionsExtensions.cs
@@ -105,7 +105,7 @@ public static SwaggerGenOptions IncludeXmlCommentsWithRemarks(
{
swaggerGenOptions.IncludeXmlComments(xmlDocFactory, includeControllerXmlComments);
- var distinctExcludedTypes = excludedTypes.Distinct().ToList();
+ var distinctExcludedTypes = excludedTypes?.Distinct().ToArray();
var xmlDoc = xmlDocFactory();
swaggerGenOptions.ParameterFilter(xmlDoc, distinctExcludedTypes);
@@ -137,6 +137,24 @@ public static SwaggerGenOptions IncludeXmlCommentsWithRemarks(
return swaggerGenOptions.IncludeXmlCommentsWithRemarks(() => new XPathDocument(filePath), includeControllerXmlComments, excludedTypes);
}
+ ///
+ /// Inject human-friendly descriptions for Schemas and it's Parameters based on <inheritdoc/> XML Comments (from summary and remarks).
+ ///
+ /// .
+ ///
+ /// Flag to indicate to include remarks from XML comments.
+ ///
+ /// Types for which remarks will be excluded.
+ public static SwaggerGenOptions IncludeXmlCommentsFromInheritDocs(
+ this SwaggerGenOptions swaggerGenOptions,
+ bool includeRemarks = false,
+ params Type[] excludedTypes)
+ {
+ var distinctExcludedTypes = excludedTypes?.Distinct().ToArray();
+ swaggerGenOptions.SchemaFilter(swaggerGenOptions, includeRemarks, distinctExcludedTypes);
+ return swaggerGenOptions;
+ }
+
#endregion
}
}
\ No newline at end of file
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/InheritDocSchemaFilter.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/InheritDocSchemaFilter.cs
new file mode 100644
index 0000000..92267a4
--- /dev/null
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/InheritDocSchemaFilter.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Xml.XPath;
+using Microsoft.OpenApi.Any;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+
+namespace Unchase.Swashbuckle.AspNetCore.Extensions.Filters
+{
+ ///
+ /// Adds documentation that is provided by the <inhertidoc /> tag.
+ ///
+ ///
+ internal class InheritDocSchemaFilter : ISchemaFilter
+ {
+ #region Fields
+
+ private const string SummaryTag = "summary";
+ private const string RemarksTag = "remarks";
+ private const string ExampleTag = "example";
+ private readonly bool _includeRemarks;
+ private readonly List _documents;
+ private readonly Dictionary _inheritedDocs;
+ private readonly Type[] _excludedTypes;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// .
+ /// Include remarks from inheritdoc XML comments.
+ /// Excluded types.
+ public InheritDocSchemaFilter(SwaggerGenOptions options, bool includeRemarks = false, params Type[] excludedTypes)
+ {
+ _includeRemarks = includeRemarks;
+ _excludedTypes = excludedTypes;
+ _documents = options.SchemaFilterDescriptors.Where(x => x.Type == typeof(XmlCommentsSchemaFilter))
+ .Select(x => x.Arguments.Single())
+ .Cast()
+ .ToList();
+
+ _inheritedDocs = _documents.SelectMany(
+ doc =>
+ {
+ var inheritedElements = new List<(string, string)>();
+ foreach (XPathNavigator member in doc.CreateNavigator().Select("doc/members/member/inheritdoc"))
+ {
+ var cref = member.GetAttribute("cref", "");
+ member.MoveToParent();
+ var parentCref = member.GetAttribute("cref", "");
+ if (!string.IsNullOrWhiteSpace(parentCref))
+ cref = parentCref;
+ inheritedElements.Add((member.GetAttribute("name", ""), cref));
+ }
+
+ return inheritedElements;
+ })
+ .ToDictionary(x => x.Item1, x => x.Item2);
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Apply filter.
+ ///
+ /// .
+ /// .
+ public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ {
+ if (_excludedTypes.Any() && _excludedTypes.ToList().Contains(context.Type))
+ {
+ return;
+ }
+
+ // Try to apply a description for inherited types.
+ var memberName = XmlCommentsNodeNameHelper.GetMemberNameForType(context.Type);
+ if (string.IsNullOrEmpty(schema.Description) && _inheritedDocs.ContainsKey(memberName))
+ {
+ var cref = _inheritedDocs[memberName];
+ var target = GetTargetRecursive(context.Type, cref);
+
+ var targetXmlNode = GetMemberXmlNode(XmlCommentsNodeNameHelper.GetMemberNameForType(target));
+ var summaryNode = targetXmlNode?.SelectSingleNode(SummaryTag);
+
+ if (summaryNode != null)
+ {
+ schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
+
+ if (_includeRemarks)
+ {
+ var remarksNode = targetXmlNode.SelectSingleNode(RemarksTag);
+ if (remarksNode != null && !string.IsNullOrWhiteSpace(remarksNode.InnerXml))
+ {
+ schema.Description += $" ({XmlCommentsTextHelper.Humanize(remarksNode.InnerXml)})";
+ }
+ }
+ }
+ }
+
+ if (schema.Properties == null)
+ return;
+
+ // Add the summary and examples for the properties.
+ foreach (var entry in schema.Properties)
+ {
+ var memberInfo = ((TypeInfo) context.Type).DeclaredMembers?.FirstOrDefault(p => p.Name.Equals(entry.Key, StringComparison.OrdinalIgnoreCase));
+ if (memberInfo != null)
+ {
+ ApplyPropertyComments(entry.Value, memberInfo);
+ }
+ }
+ }
+
+ private static MemberInfo GetTarget(MemberInfo memberInfo, string cref)
+ {
+ var type = memberInfo.DeclaringType ?? memberInfo.ReflectedType;
+
+ if (type == null)
+ return null;
+
+ // Find all matching members in all interfaces and the base class.
+ var targets = type.GetInterfaces()
+ .Append(type.BaseType)
+ .SelectMany(
+ x => x.FindMembers(
+ memberInfo.MemberType,
+ BindingFlags.Instance | BindingFlags.Public,
+ (info, criteria) => info.Name == memberInfo.Name,
+ null))
+ .ToList();
+
+ // Try to find the target, if one is declared.
+ if (!string.IsNullOrEmpty(cref))
+ {
+ var crefTarget = targets.SingleOrDefault(t => XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(t) == cref);
+
+ if (crefTarget != null)
+ return crefTarget;
+ }
+
+ // We use the last since that will be our base class or the "nearest" implemented interface.
+ return targets.LastOrDefault();
+ }
+
+ private static Type GetTarget(Type type, string cref)
+ {
+ var targets = type.GetInterfaces();
+ if (type.BaseType != typeof(object))
+ targets = targets.Append(type.BaseType).ToArray();
+
+ // Try to find the target, if one is declared.
+ if (!string.IsNullOrEmpty(cref))
+ {
+ var crefTarget = targets.SingleOrDefault(t => XmlCommentsNodeNameHelper.GetMemberNameForType(t) == cref);
+
+ if (crefTarget != null)
+ return crefTarget;
+ }
+
+ // We use the last since that will be our base class or the "nearest" implemented interface.
+ return targets.LastOrDefault();
+ }
+
+ private void ApplyPropertyComments(OpenApiSchema propertySchema, MemberInfo memberInfo)
+ {
+ var memberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(memberInfo);
+
+ if (!_inheritedDocs.ContainsKey(memberName))
+ return;
+
+ if (_excludedTypes.Any() && _excludedTypes.ToList()
+ .Contains(((PropertyInfo)memberInfo).PropertyType))
+ {
+ return;
+ }
+
+ var cref = _inheritedDocs[memberName];
+ var target = GetTargetRecursive(memberInfo, cref);
+
+ var targetXmlNode = GetMemberXmlNode(XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(target));
+
+ if (targetXmlNode == null)
+ return;
+
+ var summaryNode = targetXmlNode.SelectSingleNode(SummaryTag);
+ if (summaryNode != null)
+ {
+ propertySchema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
+
+ if (_includeRemarks)
+ {
+ var remarksNode = targetXmlNode.SelectSingleNode(RemarksTag);
+ if (remarksNode != null && !string.IsNullOrWhiteSpace(remarksNode.InnerXml))
+ {
+ propertySchema.Description += $" ({XmlCommentsTextHelper.Humanize(remarksNode.InnerXml)})";
+ }
+ }
+ }
+
+ var exampleNode = targetXmlNode.SelectSingleNode(ExampleTag);
+ if (exampleNode != null)
+ propertySchema.Example = new OpenApiString(XmlCommentsTextHelper.Humanize(exampleNode.InnerXml));
+ }
+
+ private XPathNavigator GetMemberXmlNode(string memberName)
+ {
+ var path = $"/doc/members/member[@name='{memberName}']";
+
+ foreach (var document in _documents)
+ {
+ var node = document.CreateNavigator().SelectSingleNode(path);
+
+ if (node != null)
+ return node;
+ }
+
+ return null;
+ }
+
+ private MemberInfo GetTargetRecursive(MemberInfo memberInfo, string cref)
+ {
+ var target = GetTarget(memberInfo, cref);
+
+ if (target == null)
+ return null;
+
+ var targetMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(target);
+
+ if (_inheritedDocs.ContainsKey(targetMemberName))
+ return GetTarget(target, _inheritedDocs[targetMemberName]);
+
+ return target;
+ }
+
+ private Type GetTargetRecursive(Type type, string cref)
+ {
+ var target = GetTarget(type, cref);
+
+ if (target == null)
+ return null;
+
+ var targetMemberName = XmlCommentsNodeNameHelper.GetMemberNameForType(target);
+
+ if (_inheritedDocs.ContainsKey(targetMemberName))
+ return GetTarget(target, _inheritedDocs[targetMemberName]);
+
+ return target;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksDocumentFilter.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksDocumentFilter.cs
index 0b24586..4a410ab 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksDocumentFilter.cs
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksDocumentFilter.cs
@@ -11,7 +11,7 @@ namespace Unchase.Swashbuckle.AspNetCore.Extensions.Filters
///
/// Inject human-friendly remarks to descriptions for Document's Tags based on XML Comment files.
///
- public class XmlCommentsWithRemarksDocumentFilter : IDocumentFilter
+ internal class XmlCommentsWithRemarksDocumentFilter : IDocumentFilter
{
#region Fields
@@ -56,8 +56,7 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
foreach (var nameAndType in controllerNamesAndTypes)
{
- if (_excludedTypes.ToList().Select(t => t.FullName)
- .Contains(nameAndType.Value.FullName))
+ if (_excludedTypes.Any() && _excludedTypes.ToList().Contains(nameAndType.Value))
{
continue;
}
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksParameterFilter.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksParameterFilter.cs
index ce2d133..991fa5c 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksParameterFilter.cs
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksParameterFilter.cs
@@ -10,7 +10,7 @@ namespace Unchase.Swashbuckle.AspNetCore.Extensions.Filters
///
/// Inject human-friendly remarks to descriptions for Parameters based on XML Comment files.
///
- public class XmlCommentsWithRemarksParameterFilter : IParameterFilter
+ internal class XmlCommentsWithRemarksParameterFilter : IParameterFilter
{
#region Fields
@@ -53,8 +53,7 @@ public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
private void ApplyPropertyTags(OpenApiParameter parameter, PropertyInfo propertyInfo)
{
- if (propertyInfo.DeclaringType != null && _excludedTypes.ToList().Select(t => t.FullName)
- .Contains(propertyInfo.DeclaringType?.FullName))
+ if (propertyInfo.DeclaringType != null && _excludedTypes.Any() && _excludedTypes.ToList().Contains(propertyInfo.DeclaringType))
{
return;
}
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksRequestBodyFilter.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksRequestBodyFilter.cs
index 3f4266d..d88a4e3 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksRequestBodyFilter.cs
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksRequestBodyFilter.cs
@@ -10,7 +10,7 @@ namespace Unchase.Swashbuckle.AspNetCore.Extensions.Filters
///
/// Inject human-friendly remarks to descriptions for RequestBodies based on XML Comment files.
///
- public class XmlCommentsWithRemarksRequestBodyFilter : IRequestBodyFilter
+ internal class XmlCommentsWithRemarksRequestBodyFilter : IRequestBodyFilter
{
#region Fields
@@ -59,8 +59,7 @@ public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext conte
private void ApplyPropertyTags(OpenApiRequestBody requestBody, PropertyInfo propertyInfo)
{
- if (propertyInfo.DeclaringType != null && _excludedTypes.ToList().Select(t => t.FullName)
- .Contains(propertyInfo.DeclaringType?.FullName))
+ if (propertyInfo.DeclaringType != null && _excludedTypes.Any() && _excludedTypes.ToList().Contains(propertyInfo.DeclaringType))
{
return;
}
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksSchemaFilter.cs b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksSchemaFilter.cs
index c66f442..7a5e12a 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksSchemaFilter.cs
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Filters/XmlCommentsWithRemarksSchemaFilter.cs
@@ -10,7 +10,7 @@ namespace Unchase.Swashbuckle.AspNetCore.Extensions.Filters
///
/// Inject human-friendly remarks to descriptions for Schemas based on XML Comment files.
///
- public class XmlCommentsWithRemarksSchemaFilter : ISchemaFilter
+ internal class XmlCommentsWithRemarksSchemaFilter : ISchemaFilter
{
#region Fields
@@ -59,8 +59,7 @@ public void Apply(OpenApiSchema schema, SchemaFilterContext context)
private void ApplyTypeTags(OpenApiSchema schema, Type type)
{
- if (_excludedTypes.ToList().Select(t => t.FullName)
- .Contains(type.FullName))
+ if (_excludedTypes.Any() && _excludedTypes.ToList().Contains(type))
{
return;
}
@@ -80,8 +79,7 @@ private void ApplyTypeTags(OpenApiSchema schema, Type type)
private void ApplyFieldOrPropertyTags(OpenApiSchema schema, MemberInfo fieldOrPropertyInfo)
{
- if (fieldOrPropertyInfo.DeclaringType != null && _excludedTypes.ToList().Select(t => t.FullName)
- .Contains(fieldOrPropertyInfo.DeclaringType?.FullName))
+ if (fieldOrPropertyInfo.DeclaringType != null && _excludedTypes.Any() && _excludedTypes.ToList().Contains(fieldOrPropertyInfo.DeclaringType))
{
return;
}
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.csproj b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.csproj
index f5ccaeb..24b95df 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.csproj
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.csproj
@@ -14,9 +14,9 @@
7.3
https://github.com/unchase/Unchase.Swashbuckle.AspNetCore.Extensions/blob/master/assets/icon.png?raw=true
- 2.4.1
- 2.4.1.0
- 2.4.1.0
+ 2.5.0
+ 2.5.0.0
+ 2.5.0.0
false
Unchase.Swashbuckle.AspNetCore.Extensions.xml
diff --git a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.xml b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.xml
index 69c9947..c42c625 100644
--- a/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.xml
+++ b/src/Unchase.Swashbuckle.AspNetCore.Extensions/Unchase.Swashbuckle.AspNetCore.Extensions.xml
@@ -127,6 +127,16 @@
Types for which remarks will be excluded.
+
+
+ Inject human-friendly descriptions for Schemas and it's Parameters based on <inheritdoc/> XML Comments (from summary and remarks).
+
+ .
+
+ Flag to indicate to include remarks from XML comments.
+
+ Types for which remarks will be excluded.
+
factory.
@@ -315,6 +325,27 @@
.
.
+
+
+ Adds documentation that is provided by the <inhertidoc /> tag.
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ .
+ Include remarks from inheritdoc XML comments.
+ Excluded types.
+
+
+
+ Apply filter.
+
+ .
+ .
+
Document filter for ordering tags by name in OpenApi document.
diff --git a/test/WebApi3.1-Swashbuckle/Controllers/TodoController.cs b/test/WebApi3.1-Swashbuckle/Controllers/TodoController.cs
index e9af970..2cff1f2 100644
--- a/test/WebApi3.1-Swashbuckle/Controllers/TodoController.cs
+++ b/test/WebApi3.1-Swashbuckle/Controllers/TodoController.cs
@@ -19,7 +19,7 @@ namespace WebApi3._1_Swashbuckle.Controllers
[SwaggerTag("Controller for todo")]
public class TodoController : ControllerBase
{
- private static readonly ItodoContext _context = new TodoContext();
+ private static readonly ItodoContext Context = new TodoContext();
///
/// Hided action
@@ -61,6 +61,27 @@ public ActionResult ComplicatedAction()
});
}
+ ///
+ /// InheritDoc action
+ ///
+ ///
+ /// InheritDoc action remarks
+ ///
+ /// A InheritDoc class.
+ /// Returns a InheritDoc class.
+ [HttpGet("inheritdoc")]
+ [AllowAnonymous]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult InheritDocAction()
+ {
+ return Ok(new InheritDocClass
+ {
+ Name = "Name",
+ Common = "Common",
+ InheritEnum = InheritEnum.Value
+ });
+ }
+
///
/// Deletes a specific TodoItem
///
@@ -72,14 +93,14 @@ public ActionResult ComplicatedAction()
[Authorize(Roles = "AcceptedRole")]
public IActionResult Delete(long id)
{
- var todo = _context.Find(id);
+ var todo = Context.Find(id);
if (todo == null)
{
return NotFound();
}
- _context.Remove(todo);
+ Context.Remove(todo);
return NoContent();
}
@@ -108,7 +129,7 @@ public IActionResult Delete(long id)
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult Create(TodoItem item)
{
- _context.Add(item);
+ Context.Add(item);
return new CreatedResult(string.Empty, item);
}
diff --git a/test/WebApi3.1-Swashbuckle/Models/IInheritDocClass.cs b/test/WebApi3.1-Swashbuckle/Models/IInheritDocClass.cs
new file mode 100644
index 0000000..1f97427
--- /dev/null
+++ b/test/WebApi3.1-Swashbuckle/Models/IInheritDocClass.cs
@@ -0,0 +1,19 @@
+namespace WebApi3._1_Swashbuckle.Models
+{
+ ///
+ /// InheritDocClass - inheritdoc
+ ///
+ ///
+ /// InheritDocClass remarks - inheritdoc
+ ///
+ public interface IInheritDocClass : IInheritDocCommon
+ {
+ ///
+ /// Name - inheritdoc
+ ///
+ ///
+ /// Name remarks - inheritdoc
+ ///
+ public string Name { get; set; }
+ }
+}
diff --git a/test/WebApi3.1-Swashbuckle/Models/IInheritDocCommon.cs b/test/WebApi3.1-Swashbuckle/Models/IInheritDocCommon.cs
new file mode 100644
index 0000000..e349d5b
--- /dev/null
+++ b/test/WebApi3.1-Swashbuckle/Models/IInheritDocCommon.cs
@@ -0,0 +1,24 @@
+namespace WebApi3._1_Swashbuckle.Models
+{
+ ///
+ /// IInheritDocCommon interface
+ ///
+ ///
+ /// IInheritDocCommon interface remarks
+ ///
+ public interface IInheritDocCommon
+ {
+ ///
+ /// Common - inheritdoc (inner)
+ ///
+ ///
+ /// Common remarks - inheritdoc (inner)
+ ///
+ public string Common { get; set; }
+
+ ///
+ /// InheritEnum - inheritdoc (inner)
+ ///
+ public InheritEnum InheritEnum { get; set; }
+ }
+}
diff --git a/test/WebApi3.1-Swashbuckle/Models/InheritDocClass.cs b/test/WebApi3.1-Swashbuckle/Models/InheritDocClass.cs
new file mode 100644
index 0000000..6ad59a1
--- /dev/null
+++ b/test/WebApi3.1-Swashbuckle/Models/InheritDocClass.cs
@@ -0,0 +1,15 @@
+namespace WebApi3._1_Swashbuckle.Models
+{
+ ///
+ public class InheritDocClass : IInheritDocClass
+ {
+ ///
+ public string Name { get; set; }
+
+ ///
+ public string Common { get; set; }
+
+ ///
+ public InheritEnum InheritEnum { get; set; }
+ }
+}
diff --git a/test/WebApi3.1-Swashbuckle/Models/InheritEnum.cs b/test/WebApi3.1-Swashbuckle/Models/InheritEnum.cs
new file mode 100644
index 0000000..39633df
--- /dev/null
+++ b/test/WebApi3.1-Swashbuckle/Models/InheritEnum.cs
@@ -0,0 +1,19 @@
+namespace WebApi3._1_Swashbuckle.Models
+{
+ ///
+ /// Inherit enum - enum
+ ///
+ ///
+ /// Inherit enum remarks - enum
+ ///
+ public enum InheritEnum
+ {
+ ///
+ /// Inherit enum Value
+ ///
+ ///
+ /// Inherit enum Value remarks
+ ///
+ Value = 0
+ }
+}
diff --git a/test/WebApi3.1-Swashbuckle/Startup.cs b/test/WebApi3.1-Swashbuckle/Startup.cs
index 5940d2e..6b3671c 100644
--- a/test/WebApi3.1-Swashbuckle/Startup.cs
+++ b/test/WebApi3.1-Swashbuckle/Startup.cs
@@ -8,6 +8,7 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
+using System.Runtime.InteropServices;
using System.Text.Json.Serialization;
using Unchase.Swashbuckle.AspNetCore.Extensions.Extensions;
using Unchase.Swashbuckle.AspNetCore.Extensions.Filters;
@@ -34,18 +35,22 @@ public void ConfigureServices(IServiceCollection services)
// use it if you want to hide Paths and Definitions from OpenApi documentation correctly
options.UseAllOfToExtendReferenceSchemas();
- #region AddEnumsWithValuesFixFilters
+ // if you want to add xml comments from inheritdocs (from summary and remarks) into the swagger documentation, add:
+ // you can exclude remarks for concrete types
+ options.IncludeXmlCommentsFromInheritDocs(includeRemarks: true, excludedTypes: typeof(string));
// if you want to add xml comments from summary and remarks into the swagger documentation, first of all add:
// you can exclude remarks for concrete types
var xmlFilePath = Path.Combine(AppContext.BaseDirectory, "WebApi3.1-Swashbuckle.xml");
- options.IncludeXmlCommentsWithRemarks(xmlFilePath, false,
+ options.IncludeXmlCommentsWithRemarks(filePath: xmlFilePath, includeControllerXmlComments: false,
typeof(ComplicatedClass),
typeof(InnerEnum));
// or add without remarks
//options.IncludeXmlComments(xmlFilePath);
+ #region AddEnumsWithValuesFixFilters
+
// Add filters to fix enums
// use by default:
options.AddEnumsWithValuesFixFilters();
diff --git a/test/WebApi3.1-Swashbuckle/WebApi3.1-Swashbuckle.xml b/test/WebApi3.1-Swashbuckle/WebApi3.1-Swashbuckle.xml
index 806df06..cd5726e 100644
--- a/test/WebApi3.1-Swashbuckle/WebApi3.1-Swashbuckle.xml
+++ b/test/WebApi3.1-Swashbuckle/WebApi3.1-Swashbuckle.xml
@@ -84,6 +84,16 @@
A complicated class.
Returns a complicated class.
+
+
+ InheritDoc action
+
+
+ InheritDoc action remarks
+
+ A InheritDoc class.
+ Returns a InheritDoc class.
+
Deletes a specific TodoItem
@@ -210,6 +220,71 @@
Second inner enum value remarks
+
+
+ InheritDocClass - inheritdoc
+
+
+ InheritDocClass remarks - inheritdoc
+
+
+
+
+ Name - inheritdoc
+
+
+ Name remarks - inheritdoc
+
+
+
+
+ IInheritDocCommon interface
+
+
+ IInheritDocCommon interface remarks
+
+
+
+
+ Common - inheritdoc (inner)
+
+
+ Common remarks - inheritdoc (inner)
+
+
+
+
+ InheritEnum - inheritdoc (inner)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Inherit enum - enum
+
+
+ Inherit enum remarks - enum
+
+
+
+
+ Inherit enum Value
+
+
+ Inherit enum Value remarks
+
+
Tag for TodoItem