Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -547,18 +547,22 @@ private OpenApiSchema GenerateSchemaFromFormParameters(
? formParameter.Name.ToCamelCase()
: formParameter.Name;

var schema = (formParameter.ModelMetadata != null)
var propertyInfo = formParameter.PropertyInfo();
if (!propertyInfo?.HasAttribute<SwaggerIgnoreAttribute>() ?? true)
{
var schema = (formParameter.ModelMetadata != null)
? GenerateSchema(
formParameter.ModelMetadata.ModelType,
schemaRepository,
formParameter.PropertyInfo(),
propertyInfo,
formParameter.ParameterInfo())
: new OpenApiSchema { Type = "string" };

properties.Add(name, schema);
properties.Add(name, schema);

if (formParameter.IsRequiredParameter())
requiredPropertyNames.Add(name);
if (formParameter.IsRequiredParameter())
requiredPropertyNames.Add(name);
}
}

return new OpenApiSchema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen.Test.Fixtures;

namespace Swashbuckle.AspNetCore.SwaggerGen.Test
{
Expand All @@ -27,28 +28,28 @@ public void ActionWithRouteNameMetadata()
public void ActionWithObsoleteAttribute()
{ }

public void ActionWithParameterWithBindNeverAttribute([BindNever]string param)
public void ActionWithParameterWithBindNeverAttribute([BindNever] string param)
{ }

public void ActionWithParameterWithRequiredAttribute([Required]string param)
public void ActionWithParameterWithRequiredAttribute([Required] string param)
{ }

public void ActionWithParameterWithBindRequiredAttribute([BindRequired]string param)
public void ActionWithParameterWithBindRequiredAttribute([BindRequired] string param)
{ }

public void ActionWithIntParameter(int param)
{ }

public void ActionWithIntParameterWithRangeAttribute([Range(1, 12)]int param)
public void ActionWithIntParameterWithRangeAttribute([Range(1, 12)] int param)
{ }

public void ActionWithIntParameterWithDefaultValue(int param = 1)
{ }

public void ActionWithIntParameterWithDefaultValueAttribute([DefaultValue(3)]int param)
public void ActionWithIntParameterWithDefaultValueAttribute([DefaultValue(3)] int param)
{ }

public void ActionWithIntParameterWithRequiredAttribute([Required]int param)
public void ActionWithIntParameterWithRequiredAttribute([Required] int param)
{ }

public void ActionWithIntParameterWithSwaggerIgnoreAttribute([SwaggerIgnore] int param)
Expand Down Expand Up @@ -101,10 +102,12 @@ public FileContentResult ActionWithFileResult()
public void ActionWithSwaggerIgnoreAttribute()
{ }

public void ActionHavingIFormFileParamWithFromFormAtribute([FromForm] IFormFile fileUpload)
public void ActionHavingIFormFileParamWithFromFormAttribute([FromForm] IFormFile fileUpload)
{ }

public void ActionHavingFromFormAtributeButNotWithIFormFile([FromForm] string param1, IFormFile param2)
public void ActionHavingFromFormAttributeButNotWithIFormFile([FromForm] string param1, IFormFile param2)
{ }
public void ActionHavingFromFormAttributeWithSwaggerIgnore([FromForm] SwaggerIngoreAnnotatedType param1)
{ }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;

namespace Swashbuckle.AspNetCore.SwaggerGen.Test.Fixtures
{
internal class FakeICompositeMetadataDetailsProvider : ICompositeMetadataDetailsProvider
{
public void CreateBindingMetadata(BindingMetadataProviderContext context)
{
throw new NotImplementedException();
}

public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
throw new NotImplementedException();
}

public void CreateValidationMetadata(ValidationMetadataProviderContext context)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.AspNetCore.Routing;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen.Test.Fixtures;
using Swashbuckle.AspNetCore.TestSupport;
using Xunit;

Expand Down Expand Up @@ -1593,14 +1595,14 @@ public void GetSwagger_GeneratesSwaggerDocument_ThrowsIfHttpMethodNotSupported(s
public void GetSwagger_Throws_Exception_When_FromForm_Attribute_Used_With_IFormFile()
{
var parameterInfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingIFormFileParamWithFromFormAtribute))
.GetMethod(nameof(FakeController.ActionHavingIFormFileParamWithFromFormAttribute))
.GetParameters()[0];

var subject = Subject(
apiDescriptions: new[]
{
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingIFormFileParamWithFromFormAtribute),
c => nameof(c.ActionHavingIFormFileParamWithFromFormAttribute),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
Expand All @@ -1623,18 +1625,18 @@ public void GetSwagger_Throws_Exception_When_FromForm_Attribute_Used_With_IFormF
public void GetSwagger_Works_As_Expected_When_FromForm_Attribute_Not_Used_With_IFormFile()
{
var paraminfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingFromFormAtributeButNotWithIFormFile))
.GetMethod(nameof(FakeController.ActionHavingFromFormAttributeButNotWithIFormFile))
.GetParameters()[0];

var fileUploadParameterInfo = typeof(FakeController)
.GetMethod(nameof(FakeController.ActionHavingFromFormAtributeButNotWithIFormFile))
.GetMethod(nameof(FakeController.ActionHavingFromFormAttributeButNotWithIFormFile))
.GetParameters()[1];

var subject = Subject(
apiDescriptions: new[]
{
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingFromFormAtributeButNotWithIFormFile),
c => nameof(c.ActionHavingFromFormAttributeButNotWithIFormFile),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
Expand Down Expand Up @@ -1668,6 +1670,59 @@ public void GetSwagger_Works_As_Expected_When_FromForm_Attribute_Not_Used_With_I
Assert.Equal("param2", operation.Parameters[1].Name);
}

[Fact]
public void GetSwagger_Works_As_Expected_When_FromForm_Attribute_With_SwaggerIgnore()
{
var propertyIgnored = typeof(SwaggerIngoreAnnotatedType).GetProperty(nameof(SwaggerIngoreAnnotatedType.IgnoredString));
var modelMetadataIgnored = new DefaultModelMetadata(
new DefaultModelMetadataProvider(new FakeICompositeMetadataDetailsProvider()),
new FakeICompositeMetadataDetailsProvider(),
new DefaultMetadataDetails(ModelMetadataIdentity.ForProperty(propertyIgnored, typeof(string), typeof(SwaggerIngoreAnnotatedType)), ModelAttributes.GetAttributesForProperty(typeof(SwaggerIngoreAnnotatedType), propertyIgnored)));

var propertyNotIgnored = typeof(SwaggerIngoreAnnotatedType).GetProperty(nameof(SwaggerIngoreAnnotatedType.NotIgnoredString));
var modelMetadataNotIgnored = new DefaultModelMetadata(
new DefaultModelMetadataProvider(new FakeICompositeMetadataDetailsProvider()),
new FakeICompositeMetadataDetailsProvider(),
new DefaultMetadataDetails(ModelMetadataIdentity.ForProperty(propertyNotIgnored, typeof(string), typeof(SwaggerIngoreAnnotatedType)), ModelAttributes.GetAttributesForProperty(typeof(SwaggerIngoreAnnotatedType), propertyNotIgnored)));
var subject = Subject(
apiDescriptions: new[]
{
ApiDescriptionFactory.Create<FakeController>(
c => nameof(c.ActionHavingFromFormAttributeWithSwaggerIgnore),
groupName: "v1",
httpMethod: "POST",
relativePath: "resource",
parameterDescriptions: new[]
{
new ApiParameterDescription
{
Name = nameof(SwaggerIngoreAnnotatedType.IgnoredString),
Source = BindingSource.Form,
Type = typeof(string),
ModelMetadata = modelMetadataIgnored
},
new ApiParameterDescription
{
Name = nameof(SwaggerIngoreAnnotatedType.NotIgnoredString),
Source = BindingSource.Form,
Type = typeof(string),
ModelMetadata = modelMetadataNotIgnored
}
})
}
);
var document = subject.GetSwagger("v1");

var operation = document.Paths["/resource"].Operations[OperationType.Post];
Assert.NotNull(operation.RequestBody);
Assert.Equal(new[] { "multipart/form-data" }, operation.RequestBody.Content.Keys);
var mediaType = operation.RequestBody.Content["multipart/form-data"];
Assert.NotNull(mediaType.Schema);
Assert.Equal(new[] { nameof(SwaggerIngoreAnnotatedType.NotIgnoredString) }, mediaType.Schema.Properties.Keys);
Assert.NotNull(mediaType.Encoding);
Assert.Equal(new[] { nameof(SwaggerIngoreAnnotatedType.NotIgnoredString) }, mediaType.Encoding.Keys);
}

private static SwaggerGenerator Subject(
IEnumerable<ApiDescription> apiDescriptions,
SwaggerGeneratorOptions options = null,
Expand Down
23 changes: 19 additions & 4 deletions test/WebSites/Basic/Controllers/FromFormParamsController.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace Basic.Controllers
{
public class FromFormParamsController
{
[HttpPost("registrations")]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult PostForm([FromForm]RegistrationForm form)
public IActionResult PostForm([FromForm] RegistrationForm form)
{
throw new System.NotImplementedException();
}

[HttpPost("registrationsWithIgnoreProperties")]
public IActionResult PostFormWithIgnoredProperties([FromForm] RegistrationFormWithIgnoredProperties form)
{
throw new System.NotImplementedException();
}
Expand All @@ -19,4 +26,12 @@ public class RegistrationForm

public IEnumerable<int> PhoneNumbers { get; set; }
}
}

public class RegistrationFormWithIgnoredProperties
{
[SwaggerIgnore, FromForm(Name = "internal_Name")]
public string Name { get; set; }

public IEnumerable<int> PhoneNumbers { get; set; }
}
}