Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to add parameter description attributes #1202

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace Swashbuckle.Swagger.Annotations
{
public class SwaggerDescriptionAttribute : Attribute
{
public SwaggerDescriptionAttribute(string description = null, string summary = null)
{
Description = description;
Summary = summary;
}

public string Description { get; set; }
public string Summary { get; set; }
}
}
12 changes: 12 additions & 0 deletions Swashbuckle.Core/Swagger/SchemaExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Reflection;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json.Serialization;
using Swashbuckle.Swagger.Annotations;

namespace Swashbuckle.Swagger
{
Expand Down Expand Up @@ -46,6 +47,17 @@ 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<SwaggerDescriptionAttribute>().FirstOrDefault();
schema.description = attrib != null ? attrib.Description : null;
return schema;
}

public static void PopulateFrom(this PartialSchema partialSchema, Schema schema)
{
if (schema == null) return;
Expand Down
2 changes: 1 addition & 1 deletion Swashbuckle.Core/Swagger/SchemaRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
18 changes: 12 additions & 6 deletions Swashbuckle.Core/Swagger/SwaggerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +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 Swashbuckle.Swagger.Annotations;

namespace Swashbuckle.Swagger
{
Expand Down Expand Up @@ -67,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);
}
Expand Down Expand Up @@ -142,6 +140,7 @@ private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaR
})
.ToList();

var description = apiDesc.ActionDescriptor.GetCustomAttributes<SwaggerDescriptionAttribute>().FirstOrDefault();
var responses = new Dictionary<string, Response>();
var responseType = apiDesc.ResponseType();
if (responseType == null || responseType == typeof(void))
Expand All @@ -152,12 +151,14 @@ private Operation CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaR
var operation = new Operation
{
tags = new[] { _options.GroupingKeySelector(apiDesc) },
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)
Expand Down Expand Up @@ -191,12 +192,17 @@ private Parameter CreateParameter(string location, ApiParameterDescription param
{
parameter.type = "string";
parameter.required = true;
return parameter;
return parameter;
}

parameter.required = location == "path" || !paramDesc.ParameterDescriptor.IsOptional;
parameter.@default = paramDesc.ParameterDescriptor.DefaultValue;

var description = paramDesc.ParameterDescriptor.GetCustomAttributes<SwaggerDescriptionAttribute>().FirstOrDefault();
if (description != null)
{
parameter.description = description.Description;
}
var schema = schemaRegistry.GetOrRegister(paramDesc.ParameterDescriptor.ParameterType);
if (parameter.@in == "body")
parameter.schema = schema;
Expand Down
1 change: 1 addition & 0 deletions Swashbuckle.Core/Swashbuckle.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<Compile Include="Swagger\Annotations\ApplySwaggerOperationAttributes.cs" />
<Compile Include="Swagger\Annotations\ApplySwaggerSchemaFilterAttributes.cs" />
<Compile Include="Swagger\Annotations\ApplySwaggerOperationFilterAttributes.cs" />
<Compile Include="Swagger\Annotations\SwaggerDescriptionAttribute.cs" />
<Compile Include="Swagger\Annotations\SwaggerOperationAttribute.cs" />
<Compile Include="Swagger\Annotations\SwaggerSchemaFilterAttribute.cs" />
<Compile Include="Swagger\Annotations\SwaggerOperationFilterAttribute.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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; }
}
Expand Down
5 changes: 3 additions & 2 deletions Swashbuckle.Dummy.SelfHost/Swashbuckle.Dummy.SelfHost.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -9,10 +9,11 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Swashbuckle.Dummy.SelfHost</RootNamespace>
<AssemblyName>Swashbuckle.Dummy.SelfHost</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand Down
16 changes: 8 additions & 8 deletions Swashbuckle.Dummy.SelfHost/app.config
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>
9 changes: 9 additions & 0 deletions Swashbuckle.Tests/Swagger/AnnotationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<JObject>("http://tempuri.org/swagger/docs/v1");
var description = (string)swagger["paths"]["/swaggerannotated/{id}"]["put"]["parameters"][0]["description"];

Assert.AreEqual("param description", description);
}
}
}