From 0497bc07e77ee94936553570f510eb27f0ef5847 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Fri, 8 Dec 2017 17:54:16 -0500 Subject: [PATCH 1/9] Added ability to add parameter description attributes --- Swashbuckle.Core/Swagger/SwaggerGenerator.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs index 851adfc5d..5c06f9676 100644 --- a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs +++ b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs @@ -7,6 +7,7 @@ using System.Net.Http.Formatting; using System.Net.Http; using System.Threading; +using System.ComponentModel; namespace Swashbuckle.Swagger { @@ -197,6 +198,11 @@ private Parameter CreateParameter(string location, ApiParameterDescription param parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional; parameter.@default = paramDesc.ParameterDescriptor.DefaultValue; + var description = paramDesc.ParameterDescriptor.GetCustomAttributes().FirstOrDefault(); + if (description != null) + { + parameter.description = description.Description; + } var schema = schemaRegistry.GetOrRegister(paramDesc.ParameterDescriptor.ParameterType); if (parameter.@in == "body") parameter.schema = schema; From 56c764da70ff27dcf5cfa012262ebf3d03c68e88 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 11 Dec 2017 11:06:42 -0500 Subject: [PATCH 2/9] Added SwaggerDescriptionAttribute to match what was done in netcore version. Added unit test --- .../Annotations/SwaggerDescriptionAttribute.cs | 17 +++++++++++++++++ Swashbuckle.Core/Swagger/SwaggerGenerator.cs | 7 ++----- Swashbuckle.Core/Swashbuckle.Core.csproj | 1 + .../Controllers/SwaggerAnnotatedController.cs | 4 +++- Swashbuckle.Tests/Swagger/AnnotationsTests.cs | 9 +++++++++ 5 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs diff --git a/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs b/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs new file mode 100644 index 000000000..e273d7b14 --- /dev/null +++ b/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Swashbuckle.Swagger.Annotations +{ + public class SwaggerDescriptionAttribute : Attribute + { + public SwaggerDescriptionAttribute(string description = null) + { + this.Description = description; + } + + public string Description { get; set; } + } +} diff --git a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs index 5c06f9676..e5d2b369c 100644 --- a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs +++ b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs @@ -3,11 +3,8 @@ using System.Web.Http.Description; using System; using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using System.Net.Http.Formatting; -using System.Net.Http; using System.Threading; -using System.ComponentModel; +using Swashbuckle.Swagger.Annotations; namespace Swashbuckle.Swagger { @@ -198,7 +195,7 @@ private Parameter CreateParameter(string location, ApiParameterDescription param parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional; parameter.@default = paramDesc.ParameterDescriptor.DefaultValue; - var description = paramDesc.ParameterDescriptor.GetCustomAttributes().FirstOrDefault(); + var description = paramDesc.ParameterDescriptor.GetCustomAttributes().FirstOrDefault(); if (description != null) { parameter.description = description.Description; diff --git a/Swashbuckle.Core/Swashbuckle.Core.csproj b/Swashbuckle.Core/Swashbuckle.Core.csproj index d830ccbba..1b16af32a 100644 --- a/Swashbuckle.Core/Swashbuckle.Core.csproj +++ b/Swashbuckle.Core/Swashbuckle.Core.csproj @@ -70,6 +70,7 @@ + diff --git a/Swashbuckle.Dummy.Core/Controllers/SwaggerAnnotatedController.cs b/Swashbuckle.Dummy.Core/Controllers/SwaggerAnnotatedController.cs index c091fa55e..97acdc3d8 100644 --- a/Swashbuckle.Dummy.Core/Controllers/SwaggerAnnotatedController.cs +++ b/Swashbuckle.Dummy.Core/Controllers/SwaggerAnnotatedController.cs @@ -32,7 +32,8 @@ public Message GetById(int id) [HttpPut] [SwaggerOperation("UpdateMessage", Tags = new[] { "messages" }, Schemes = new[] { "ws" })] - public void Put(int id, Message message) + + public void Put([SwaggerDescription("param description")]int id, Message message) { throw new NotImplementedException(); } @@ -41,6 +42,7 @@ public void Put(int id, Message message) [SwaggerSchemaFilter(typeof(AddMessageDefault))] public class Message { + [SwaggerDescription("param model description")] public string Title { get; set; } public string Content { get; set; } } diff --git a/Swashbuckle.Tests/Swagger/AnnotationsTests.cs b/Swashbuckle.Tests/Swagger/AnnotationsTests.cs index 45ca5ebbe..e7c145016 100644 --- a/Swashbuckle.Tests/Swagger/AnnotationsTests.cs +++ b/Swashbuckle.Tests/Swagger/AnnotationsTests.cs @@ -138,5 +138,14 @@ public void It_supports_per_action_filters_via_swagger_operation_filter_attribut Assert.AreEqual(expected.ToString(), responseExamples.ToString()); } + + [Test] + public void It_has_parameter_descriptions() + { + var swagger = GetContent("http://tempuri.org/swagger/docs/v1"); + var description = (string)swagger["paths"]["/swaggerannotated/{id}"]["put"]["parameters"][0]["description"]; + + Assert.AreEqual("param description", description); + } } } From 50039e6ed09c6e1af51c1c67210c4f281258bb71 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Tue, 12 Dec 2017 11:36:00 -0500 Subject: [PATCH 3/9] Added SwaggerDescription to model properties. --- Swashbuckle.Core/Swagger/SchemaExtensions.cs | 13 +++++++++++++ Swashbuckle.Core/Swagger/SchemaRegistry.cs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Swashbuckle.Core/Swagger/SchemaExtensions.cs b/Swashbuckle.Core/Swagger/SchemaExtensions.cs index a1c5c63bd..acdaaff1c 100644 --- a/Swashbuckle.Core/Swagger/SchemaExtensions.cs +++ b/Swashbuckle.Core/Swagger/SchemaExtensions.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.ComponentModel.DataAnnotations; using Newtonsoft.Json.Serialization; +using Swashbuckle.Swagger.Annotations; namespace Swashbuckle.Swagger { @@ -46,6 +47,18 @@ public static Schema WithValidationProperties(this Schema schema, JsonProperty j return schema; } + public static Schema WithDescriptionProperty(this Schema schema, JsonProperty jsonProperty) + { + var propInfo = jsonProperty.PropertyInfo(); + if (propInfo == null) + return schema; + + var attrib = propInfo.GetCustomAttributes(false).OfType().FirstOrDefault(); + schema.description = attrib?.Description; + + return schema; + } + public static void PopulateFrom(this PartialSchema partialSchema, Schema schema) { if (schema == null) return; diff --git a/Swashbuckle.Core/Swagger/SchemaRegistry.cs b/Swashbuckle.Core/Swagger/SchemaRegistry.cs index 4a37f92e6..083e02787 100644 --- a/Swashbuckle.Core/Swagger/SchemaRegistry.cs +++ b/Swashbuckle.Core/Swagger/SchemaRegistry.cs @@ -240,7 +240,7 @@ private Schema CreateObjectSchema(JsonObjectContract jsonContract) .Where(p => !(_ignoreObsoleteProperties && p.IsObsolete())) .ToDictionary( prop => prop.PropertyName, - prop => CreateInlineSchema(prop.PropertyType).WithValidationProperties(prop) + prop => CreateInlineSchema(prop.PropertyType).WithValidationProperties(prop).WithDescriptionProperty(prop) ); var required = jsonContract.Properties.Where(prop => prop.IsRequired()) From 8ad8bffe4d091fa9c49ba1666f29bf0b6b77b737 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Thu, 21 Dec 2017 18:58:27 -0500 Subject: [PATCH 4/9] Adds summary to description attribute --- .../Swagger/Annotations/SwaggerDescriptionAttribute.cs | 9 ++++----- Swashbuckle.Core/Swagger/SwaggerGenerator.cs | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs b/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs index e273d7b14..9ad83379d 100644 --- a/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs +++ b/Swashbuckle.Core/Swagger/Annotations/SwaggerDescriptionAttribute.cs @@ -1,17 +1,16 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace Swashbuckle.Swagger.Annotations { public class SwaggerDescriptionAttribute : Attribute { - public SwaggerDescriptionAttribute(string description = null) + public SwaggerDescriptionAttribute(string description = null, string summary = null) { - this.Description = description; + Description = description; + Summary = summary; } public string Description { get; set; } + public string Summary { get; set; } } } diff --git a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs index e5d2b369c..2d12dcb83 100644 --- a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs +++ b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs @@ -140,6 +140,7 @@ private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaR }) .ToList(); + var description = apiDesc.ActionDescriptor.GetCustomAttributes().FirstOrDefault(); var responses = new Dictionary(); var responseType = apiDesc.ResponseType(); if (responseType == null || responseType == typeof(void)) @@ -150,6 +151,8 @@ private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaR var operation = new Operation { tags = new[] { _options.GroupingKeySelector(apiDesc) }, + description = description?.Description, + summary = description?.Summary, operationId = apiDesc.FriendlyId(), produces = apiDesc.Produces().ToList(), consumes = apiDesc.Consumes().ToList(), From 2b601533e2360c5de09f68e50412b1e910ea30c3 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Sun, 24 Dec 2017 23:16:41 -0500 Subject: [PATCH 5/9] Updating C# minor version --- Swashbuckle.Core/Swashbuckle.Core.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Swashbuckle.Core/Swashbuckle.Core.csproj b/Swashbuckle.Core/Swashbuckle.Core.csproj index 1b16af32a..c5af2d39f 100644 --- a/Swashbuckle.Core/Swashbuckle.Core.csproj +++ b/Swashbuckle.Core/Swashbuckle.Core.csproj @@ -25,6 +25,7 @@ prompt 4 false + latest pdbonly From 5c0469c17927a34d7e271c5ca84374502cb4a03a Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Sun, 24 Dec 2017 23:40:04 -0500 Subject: [PATCH 6/9] Revert "Updating C# minor version" This reverts commit 2b601533e2360c5de09f68e50412b1e910ea30c3. --- Swashbuckle.Core/Swashbuckle.Core.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Swashbuckle.Core/Swashbuckle.Core.csproj b/Swashbuckle.Core/Swashbuckle.Core.csproj index c5af2d39f..1b16af32a 100644 --- a/Swashbuckle.Core/Swashbuckle.Core.csproj +++ b/Swashbuckle.Core/Swashbuckle.Core.csproj @@ -25,7 +25,6 @@ prompt 4 false - latest pdbonly From 88cf5e1c0e9db7a010a0db118b454e1b0a38051a Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Sun, 24 Dec 2017 23:50:27 -0500 Subject: [PATCH 7/9] Trying to change .net version on Selfhost --- .../Swashbuckle.Dummy.SelfHost.csproj | 5 +++-- Swashbuckle.Dummy.SelfHost/app.config | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Swashbuckle.Dummy.SelfHost/Swashbuckle.Dummy.SelfHost.csproj b/Swashbuckle.Dummy.SelfHost/Swashbuckle.Dummy.SelfHost.csproj index 47a767487..93eba0afd 100644 --- a/Swashbuckle.Dummy.SelfHost/Swashbuckle.Dummy.SelfHost.csproj +++ b/Swashbuckle.Dummy.SelfHost/Swashbuckle.Dummy.SelfHost.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,10 +9,11 @@ Properties Swashbuckle.Dummy.SelfHost Swashbuckle.Dummy.SelfHost - v4.5 + v4.6 512 ..\ true + AnyCPU diff --git a/Swashbuckle.Dummy.SelfHost/app.config b/Swashbuckle.Dummy.SelfHost/app.config index 4f888434c..d1858bfd1 100644 --- a/Swashbuckle.Dummy.SelfHost/app.config +++ b/Swashbuckle.Dummy.SelfHost/app.config @@ -1,19 +1,19 @@ - + - - + + - - + + - - + + - \ No newline at end of file + From f24d0e4e12ac416bfdba0d51f5f521d595a965ac Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Sun, 24 Dec 2017 23:57:34 -0500 Subject: [PATCH 8/9] I give up. Removing null conditional operator --- Swashbuckle.Core/Swagger/SwaggerGenerator.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs index 2d12dcb83..96b1f6129 100644 --- a/Swashbuckle.Core/Swagger/SwaggerGenerator.cs +++ b/Swashbuckle.Core/Swagger/SwaggerGenerator.cs @@ -65,7 +65,7 @@ public SwaggerDocument GetSwagger(string rootUrl, string apiVersion) securityDefinitions = _options.SecurityDefinitions }; - foreach(var filter in _options.DocumentFilters) + foreach (var filter in _options.DocumentFilters) { filter.Apply(swaggerDoc, schemaRegistry, _apiExplorer); } @@ -151,14 +151,14 @@ private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaR var operation = new Operation { tags = new[] { _options.GroupingKeySelector(apiDesc) }, - description = description?.Description, - summary = description?.Summary, + description = description != null ? description.Description : null, + summary = description != null ? description.Summary : null, operationId = apiDesc.FriendlyId(), produces = apiDesc.Produces().ToList(), consumes = apiDesc.Consumes().ToList(), parameters = parameters.Any() ? parameters : null, // parameters can be null but not empty responses = responses, - deprecated = apiDesc.IsObsolete() ? true : (bool?) null + deprecated = apiDesc.IsObsolete() ? true : (bool?)null }; foreach (var filter in _options.OperationFilters) @@ -192,7 +192,7 @@ private Parameter CreateParameter(string location, ApiParameterDescription param { parameter.type = "string"; parameter.required = true; - return parameter; + return parameter; } parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional; From 4ff1032527454a8ffd9ce3113276901bdfac34c4 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 25 Dec 2017 00:00:55 -0500 Subject: [PATCH 9/9] Forgot one --- Swashbuckle.Core/Swagger/SchemaExtensions.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Swashbuckle.Core/Swagger/SchemaExtensions.cs b/Swashbuckle.Core/Swagger/SchemaExtensions.cs index acdaaff1c..41d050e98 100644 --- a/Swashbuckle.Core/Swagger/SchemaExtensions.cs +++ b/Swashbuckle.Core/Swagger/SchemaExtensions.cs @@ -54,8 +54,7 @@ public static Schema WithDescriptionProperty(this Schema schema, JsonProperty js return schema; var attrib = propInfo.GetCustomAttributes(false).OfType().FirstOrDefault(); - schema.description = attrib?.Description; - + schema.description = attrib != null ? attrib.Description : null; return schema; }