Skip to content

Commit 0fb4b06

Browse files
pixellospixellos
authored andcommitted
Read example/summary from positional records (domaindrivendev#2546)
Add support for reading summary and example from default type constructor for C# 9 records. Resolves domaindrivendev#1920. --------- Co-authored-by: pixellos <[email protected]>
1 parent 0c4a175 commit 0fb4b06

File tree

3 files changed

+74
-10
lines changed

3 files changed

+74
-10
lines changed

src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsSchemaFilter.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,41 @@ private void ApplyMemberTags(OpenApiSchema schema, SchemaFilterContext context)
3939
var fieldOrPropertyMemberName = XmlCommentsNodeNameHelper.GetMemberNameForFieldOrProperty(context.MemberInfo);
4040
var fieldOrPropertyNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{fieldOrPropertyMemberName}']");
4141

42-
if (fieldOrPropertyNode == null) return;
42+
var recordTypeName = XmlCommentsNodeNameHelper.GetMemberNameForType(context.MemberInfo.DeclaringType);
43+
var recordDefaultConstructorProperty =
44+
_xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{recordTypeName}']/param[@name='{context.MemberInfo.Name}']");
4345

44-
var summaryNode = fieldOrPropertyNode.SelectSingleNode("summary");
45-
if (summaryNode != null)
46-
schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
46+
if (recordDefaultConstructorProperty != null)
47+
{
48+
var summaryNode = recordDefaultConstructorProperty.Value;
49+
if (summaryNode != null)
50+
schema.Description = XmlCommentsTextHelper.Humanize(summaryNode);
51+
52+
var example = recordDefaultConstructorProperty.GetAttribute("example", string.Empty);
53+
TrySetExample(schema, context, example);
54+
}
4755

48-
var exampleNode = fieldOrPropertyNode.SelectSingleNode("example");
49-
if (exampleNode != null)
56+
if (fieldOrPropertyNode != null)
5057
{
51-
var exampleAsJson = (schema.ResolveType(context.SchemaRepository) == "string") && !exampleNode.Value.Equals("null")
52-
? $"\"{exampleNode.ToString()}\""
53-
: exampleNode.ToString();
58+
var summaryNode = fieldOrPropertyNode.SelectSingleNode("summary");
59+
if (summaryNode != null)
60+
schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml);
5461

55-
schema.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson);
62+
var exampleNode = fieldOrPropertyNode.SelectSingleNode("example");
63+
TrySetExample(schema, context, exampleNode?.Value);
5664
}
5765
}
66+
67+
private static void TrySetExample(OpenApiSchema schema, SchemaFilterContext context, string example)
68+
{
69+
if (example == null)
70+
return;
71+
72+
var exampleAsJson = (schema.ResolveType(context.SchemaRepository) == "string") && !example.Equals("null")
73+
? $"\"{example}\""
74+
: example;
75+
76+
schema.Example = OpenApiAnyFactory.CreateFromJson(exampleAsJson);
77+
}
5878
}
5979
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using Swashbuckle.AspNetCore.TestSupport;
3+
4+
namespace Swashbuckle.AspNetCore.SwaggerGen.Test
5+
{
6+
/// <summary>
7+
/// Summary for XmlAnnotatedType
8+
/// </summary>
9+
/// <param name="BoolProperty" example="true">Summary for BoolProperty</param>
10+
/// <param name="IntProperty" example="10">Summary for IntProperty</param>
11+
/// <param name="LongProperty" example="4294967295">Summary for LongProperty</param>
12+
/// <param name="FloatProperty" example="1.2">Summary for FloatProperty</param>
13+
/// <param name="DoubleProperty" example="1.25">Summary for DoubleProperty</param>
14+
/// <param name="EnumProperty" example="2">Summary for EnumProperty</param>
15+
/// <param name="GuidProperty" example="d3966535-2637-48fa-b911-e3c27405ee09">Summary for GuidProperty</param>
16+
/// <param name="StringPropertyWithNullExample" example="null">Summary for Nullable StringPropertyWithNullExample</param>
17+
/// <param name="StringProperty" example="Example for StringProperty">Summary for StringProperty</param>
18+
/// <param name="StringPropertyWithUri" example="https://test.com/a?b=1&amp;c=2">Summary for StringPropertyWithUri</param>
19+
/// <param name="ObjectProperty" example="{&quot;prop1&quot;: 1, &quot;prop2&quot;: &quot;foobar&quot;}">Summary for ObjectProperty</param>
20+
public record XmlAnnotatedRecord(
21+
bool BoolProperty,
22+
int IntProperty,
23+
long LongProperty,
24+
float FloatProperty,
25+
double DoubleProperty,
26+
IntEnum EnumProperty,
27+
Guid GuidProperty,
28+
string StringPropertyWithNullExample,
29+
string StringProperty,
30+
string StringPropertyWithUri,
31+
object ObjectProperty
32+
);
33+
}

test/Swashbuckle.AspNetCore.SwaggerGen.Test/XmlComments/XmlCommentsSchemaFilterTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ public void Apply_SetsDescription_FromPropertySummaryTag(
6868
[InlineData(typeof(XmlAnnotatedType), nameof(XmlAnnotatedType.ObjectProperty), "object", "{\n \"prop1\": 1,\n \"prop2\": \"foobar\"\n}")]
6969
[InlineData(typeof(XmlAnnotatedType), nameof(XmlAnnotatedType.StringPropertyWithNullExample), "string", "null")]
7070
[InlineData(typeof(XmlAnnotatedType), nameof(XmlAnnotatedType.StringPropertyWithUri), "string", "\"https://test.com/a?b=1&c=2\"")]
71+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.BoolProperty), "boolean", "true")]
72+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.IntProperty), "integer", "10")]
73+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.LongProperty), "integer", "4294967295")]
74+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.FloatProperty), "number", "1.2")]
75+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.DoubleProperty), "number", "1.25")]
76+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.EnumProperty), "integer", "2")]
77+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.GuidProperty), "string", "\"d3966535-2637-48fa-b911-e3c27405ee09\"")]
78+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.StringProperty), "string", "\"Example for StringProperty\"")]
79+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.ObjectProperty), "object", "{\n \"prop1\": 1,\n \"prop2\": \"foobar\"\n}")]
80+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.StringPropertyWithNullExample), "string", "null")]
81+
[InlineData(typeof(XmlAnnotatedRecord), nameof(XmlAnnotatedRecord.StringPropertyWithUri), "string", "\"https://test.com/a?b=1&c=2\"")]
7182
[UseInvariantCulture]
7283
public void Apply_SetsExample_FromPropertyExampleTag(
7384
Type declaringType,

0 commit comments

Comments
 (0)