Git Product home page Git Product logo

swashbuckle.aspnetcore.filters's Introduction

Swashbuckle.AspNetCore.Filters

Build status NuGet

๐Ÿ“ฃ Rename to Swashbuckle.AspNetCore.Filters
This project was formerly called Swashbuckle.AspNetCore.Examples, but it has grown from there to become a grab-bag of various filters I have created (or copied) since I started used Swashbuckle in 2015. So I have renamed it.

This library contains a bunch of filters for Swashbuckle.AspNetCore.

Table of Contents

Changelog

See the CHANGELOG.md.

Where to get it

From NuGet.

Version of Swashbuckle you're using You'll want this version of this package
Swashbuckle 1.0 - 5.5 https://www.nuget.org/packages/Swashbuckle.Examples/
Swashbuckle.AspNetCore version 1.0.0 - 2.5.0 https://www.nuget.org/packages/Swashbuckle.AspNetCore.Examples/
Swashbuckle.AspNetCore version 3.0.0 https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/
Swashbuckle.AspNetCore version 4.0.0 and above https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ Version >= 4.5.1
Swashbuckle.AspNetCore version 5.0.0-beta and above https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ Version >= 5.0.0-beta

What's included

Request example

Populate swagger's paths.path.[http-verb].requestBody.content.[content-type].example with whatever object you like.

This is great for manually testing and demoing your API as it will prepopulate the request with some useful data, so that when you click the example request in order to populate the form, instead of getting an autogenerated request like this:

autogenerated request with crappy data

Youโ€™ll get your desired example, with useful valid data, like this:

custom request with awesome data

You can see the example output in the underlying swagger.json file, which you can get to by starting your solution and navigating to swagger/v1/swagger.json

swagger.json

As of version 5.0.0-beta, XML examples are also supported.

Response example

Allows you to add custom data to the example response shown in Swagger. So instead of seeing the default boring data like so:

response with crappy data

You'll see some more realistic data (or whatever you want):

response with awesome data

As of version 5.0.0-beta, XML examples are also supported.

Security requirements filter

Adds security information to each operation so that you can send an Authorization header to your API. Useful for API endpoints that have JWT token authentication. e.g.

authorization button

bearer token

Add a request header

Adds any string to your request headers for all requests. I use this for adding a correlationId to all requests. request header

Add a response header

Allows you to specify response headers for any operation response headers

Add Authorization to Summary

If you use the [Authorize] attribute to your controller or to any actions, then (Auth) is added to the action's summary, along with any specified policies or roles.

authorization

Installation

  1. Install the NuGet package

  2. In the ConfigureServices method of Startup.cs, inside your AddSwaggerGen call, enable whichever filters you need

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
        
        // [SwaggerRequestExample] & [SwaggerResponseExample]
        // version < 3.0 like this: c.OperationFilter<ExamplesOperationFilter>(); 
        // version 3.0 like this: c.AddSwaggerExamples(services.BuildServiceProvider());
        // version > 4.0 like this:
        c.ExampleFilters();
        
        c.OperationFilter<AddHeaderOperationFilter>("correlationId", "Correlation Id for the request", false); // adds any string you like to the request headers - in this case, a correlation id
        c.OperationFilter<AddResponseHeadersFilter>(); // [SwaggerResponseHeader]

        var filePath = Path.Combine(AppContext.BaseDirectory, "WebApi.xml");
        c.IncludeXmlComments(filePath); // standard Swashbuckle functionality, this needs to be before c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>()

        c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>(); // Adds "(Auth)" to the summary so that you can see which endpoints have Authorization
        // or use the generic method, e.g. c.OperationFilter<AppendAuthorizeToSummaryOperationFilter<MyCustomAttribute>>();

        // add Security information to each operation for OAuth2
        c.OperationFilter<SecurityRequirementsOperationFilter>();
        // or use the generic method, e.g. c.OperationFilter<SecurityRequirementsOperationFilter<MyCustomAttribute>>();

        // if you're using the SecurityRequirementsOperationFilter, you also need to tell Swashbuckle you're using OAuth2
        c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
            In = ParameterLocation.Header,
            Name = "Authorization",
            Type = SecuritySchemeType.ApiKey
        });
    });
}
  1. If you want to use the Request and Response example filters (and have called c.ExampleFilters() above), then you MUST also call
    services.AddSwaggerExamplesFromAssemblyOf<MyExample>();

or

    services.AddSwaggerExamplesFromAssemblyOf(typeof(MyExample));

or

    services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());

This will register your examples with the ServiceProvider.

Serialize Swagger in the 2.0 format

There are two ways to tell Swashbuckle.AspNetCore to output the swagger.json in the legacy Swagger 2.0 format:

app.UseSwagger(c => c.SerializeAsV2 = true);

// OR

services.Configure<SwaggerOptions>(c => c.SerializeAsV2 = true);

If you want to SerializeAsV2 and you're using my Request example filter then you must call services.Configure<SwaggerOptions>(c => c.SerializeAsV2 = true);.

How to use

How to use - Request examples

DO NOT USE THIS FILTER UNLESS YOU HAVE TO

Since May 2018, Swashbuckle.AspNetCore supports adding examples via XML comments:

public class Product
{
    /// <summary>
    /// The name of the product
    /// </summary>
    /// <example>Men's basketball shoes</example>
    public string Name { get; set; }

This works for request examples and response examples, and it even works for example querystring and route parameters, i.e. on GET requests!

Example in a querystring on GET:

example on querystring

Example request body in a POST:

example request body

Example response:

example response

And soon (April 2020, once my Swashbuckle.AspNetCore PR has been released) you'll be able to add examples for primitive types on the querystring too, e.g.

/// <param name="id" example="123">The product id</param>
[HttpGet("{id}")]
public Product GetById(int id)

See the instructions on Swashbuckle.AspNetCore's Readme.

Therefore, I recommend that you move away from using my ExamplesOperationFilter. Personally, I don't use it any more and would like to deprecate it.

However, you may have a use case where XML comments doesn't work for you, e.g.

  • You want to generate examples at runtime not design time
  • You need XML request examples (not JSON)
  • You want examples to be added to the schema under the path, rather than the schema under the component
  • Some other ReDoc issue which I don't understand as I don't use ReDoc...

In which case, read on...

Automatic annotation

Version 4.0 and above supports automatic annotation.

Let's say you have a controller action which takes some input from the body, in this case a DeliveryOptionsSearchModel:

[HttpPost]
public async Task<IHttpActionResult> DeliveryOptionsForAddress([FromBody]DeliveryOptionsSearchModel search)

Then all you need to do is implement IExamplesProvider<DeliveryOptionsSearchModel>:

public class DeliveryOptionsSearchModelExample : IExamplesProvider<DeliveryOptionsSearchModel>
{
    public DeliveryOptionsSearchModel GetExamples()
    {
        return new DeliveryOptionsSearchModel
        {
            Lang = "en-GB",
            Currency = "GBP",
            Address = new AddressModel
            {
                Address1 = "1 Gwalior Road",
                Locality = "London",
                Country = "GB",
                PostalCode = "SW15 1NP"
            }
        };
    }

And that's it.

Manual annotation

Alternatively, if you want to be more explicit, you can use the SwaggerRequestExample attribute. This is how it was done in versions 1.0 - 3.0. Any manual annotations will override automatic annotations.

Decorate your controller methods with the included SwaggerRequestExample attribute:

[HttpPost]
[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]
public async Task<IHttpActionResult> DeliveryOptionsForAddress([FromBody]DeliveryOptionsSearchModel search)

Now implement a IExamplesProvider<T>, in this case via a DeliveryOptionsSearchModelExample which will generate the example data. It should return the type you specified when you specified the [SwaggerRequestExample].

public class DeliveryOptionsSearchModelExample : IExamplesProvider<DeliveryOptionsSearchModel>
{
    public DeliveryOptionsSearchModel GetExamples()
    {
        return new DeliveryOptionsSearchModel
        {
            Lang = "en-GB",
            Currency = "GBP",
            Address = new AddressModel
            {
                Address1 = "1 Gwalior Road",
                Locality = "London",
                Country = "GB",
                PostalCode = "SW15 1NP"
            },
            Items = new[]
            {
                new ItemModel
                {
                    ItemId = "ABCD",
                    ItemType = ItemType.Product,
                    Price = 20,
                    Quantity = 1,
                    RestrictedCountries = new[] { "US" }
                }
            }
        };
    }

In the Swagger document, this will populate the operation's requestBody content type example property. https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject

Here's what the OpenApi 3.0 spec says about it:

Field Name Type Description
example Any Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example object is mutually exclusive of the examples object. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema.

List Request examples

As of version 2.4, List<T> request examples are supported. For any List<T> in the request, you may define a SwaggerRequestExample for T. Your IExamplesProvider should only return a single T and not a List<T>. Working example:

[SwaggerRequestExample(typeof(PeopleRequest), typeof(ListPeopleRequestExample))]
public IEnumerable<PersonResponse> GetPersonList([FromBody]List<PeopleRequest> peopleRequest)
{

// and then:

public class ListPeopleRequestExample : IExamplesProvider<PeopleRequest>
{
    public PeopleRequest GetExamples()
    {
        return new PeopleRequest { Title = Title.Mr, Age = 24, FirstName = "Dave in a list", Income = null };
    }
}

How to use - Response examples

AGAIN, DO NOT USE THIS FILTER UNLESS YOU HAVE TO

I repeat my earlier assertion - Since May 2018, Swashbuckle.AspNetCore supports adding examples via XML comments.

See above for instructions

If you still want to use it, read on...

Automatic annotation

Version 4.0 supports automatic annotation. If it's obvious which type your action returns, then no ProducesResponseType or SwaggerResponse attributes need to be specified, e.g.

public async Task<ActionResult<IEnumerable<Country>>> Get(string lang)
// or public ActionResult<IEnumerable<Country>> Get(string lang)
// or public IEnumerable<Country> Get(string lang)

Manual annotation

Alternatively, if you want to be more explicit, you can use the SwaggerResponseExample attribute. This is how it was done in versions 1.0 - 3.0. Any manual annotations will override automatic annotations.

Decorate your methods with the new SwaggerResponseExample attribute:

[SwaggerResponse(200, "The list of countries", typeof(IEnumerable<Country>))]
// or, like this [ProducesResponseType(typeof(IEnumerable<Country>), 200)]
[SwaggerResponseExample(200, typeof(CountryExamples))]
[SwaggerResponse(400, type: typeof(IEnumerable<ErrorResource>))]
public async Task<HttpResponseMessage> Get(string lang)

For manual annotation implement IExamplesProvider<T> to generate the example data

public class CountryExamples : IExamplesProvider<List<Country>>
{
    public List<Country> GetExamples()
    {
        return new List<Country>
        {
            new Country { Code = "AA", Name = "Test Country" },
            new Country { Code = "BB", Name = "And another" }
        };
    }
}

In the Swagger document, this will populate the operation's responses content example object. The spec for this says:

Field Pattern Type Description
example Any Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example object is mutually exclusive of the examples object. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema.

Example response for application/json mimetype of a Pet data type:

 "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                },
                "example": "{\r\n  \"name\": \"Lassie\",\r\n  \"type\": \"Dog\",\r\n  \"color\": \"Black\",\r\n  \"gender\": \"Femail\",\r\n  \"breed\": \"Collie\" \r\n}"
              },

Known issues

  • Request examples are not shown for querystring parameters (i.e. HTTP GET requests, or for querystring parameters for POST, PUT etc methods). Request examples will only be shown in request body. You can use Swashbuckle.AspNetCore's built-in XML comments to add examples for primitive types.

How to use - Multiple examples

Sometimes more than a single example are desirable for an API. In this case you can use IMultipleExamplesProvider<T> rather than IExamplesProvider<T> to return multiple examples. The example provider class is still located in the same way (automatic or manual annotation), but the GetExamples() call returns an enumerated list of examples along with their name and optional summary. To reduce boilerplate, it is recommended to use yield return for each example value. Every returned SwaggerExample<T> should have different value of Name property.

public class DeliveryOptionsSearchModelExample : IMultipleExamplesProvider<DeliveryOptionsSearchModel>
{
    public IEnumerable<SwaggerExample<DeliveryOptionsSearchModel>> GetExamples()
    {
        // An example without a summary.
        yield return SwaggerExample.Create(
            "Great Britain",
            "Here's an optional description" // optional description - Markdown is supported
            new DeliveryOptionsSearchModel
            {
                Lang = "en-GB",
                Currency = "GBP",
                Address = new AddressModel
                {
                    Address1 = "1 Gwalior Road",
                    Locality = "London",
                    Country = "GB",
                    PostalCode = "SW15 1NP"
                }
            }
        );

        // An example with a summary.
        yield return SwaggerExample.Create(
            "United States",
            "A minor former colony of Great Britain",
            new DeliveryOptionsSearchModel
            {
                Lang = "en-US",
                Currency = "USD",
                Address = new AddressModel
                {
                    Address1 = "123 Main Street",
                    Locality = "New York",
                    Country = "US",
                    PostalCode = "10001"
                }
            },
        );
    }

Note that UIs may choose to display the summary in different ways; in ReDoc, for example, the summary (if present) replaces the name in the UI.

How to use - Security requirements filter

First you need to already have OAuth2 configured correctly, and some of your controllers and actions locked down with the [Authorize] attribute. N.B. globally registered Authorization filters are not detected.

Then you need to tell Swagger that you're using OAuth2, as shown in the Installation section above:

    services.AddSwaggerGen(c =>
    {
        c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Description = "Standard Authorization header using the Bearer scheme. Example: \"bearer {token}\"",
            In = ParameterLocation.Header,
            Name = "Authorization",
            Type = SecuritySchemeType.ApiKey
        });

This adds a securityDefinition to the bottom of the Swagger document, which Swagger-UI renders as an "Authorize" button, which when clicked brings up the Authorize dialog box shown above.

Then, when you enable the SecurityRequirementsOperationFilter:

	// add Security information to each operation for OAuth2
	c.OperationFilter<SecurityRequirementsOperationFilter>();

It adds a security property to each operation, which renders in Swagger-UI as a padlock next to the operation: locked down actions

By default, the SecurityRequirementsOperationFilter also adds 401 and 403 to each operation that has [Authorize] on it: 401 and 403

If you don't want to do that you can pass false when you configure it:

	c.OperationFilter<SecurityRequirementsOperationFilter>(false);

How to use - Request Header

When you enable the filter in your Startup.cs, as per the Installation section above, you can specify the name (string) and description (string) of the new header parameter, as well as whether it is required or not (bool). This will add the input box to every controller action.

How to use - Response headers

Specify one or more [SwaggerResponseHeader] attributes on your controller action. You can specify the status code (int), header name (string), type (string), description (string) and format (string). See the OpenAPI Specification spec for information on DataTypes: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#dataTypes

[SwaggerResponseHeader(StatusCodes.Status200OK, "Location", "string", "Location of the newly created resource")]
[SwaggerResponseHeader(200, "ETag", "string", "An ETag of the resource")]
[SwaggerResponseHeader(429, "Retry-After", "integer", "Indicates how long to wait before making a new request.", "int32")]
[SwaggerResponseHeader(new int[] { 200, 401, 403, 404 }, "CustomHeader", "string", "A custom header")]
public IHttpActionResult GetPerson(PersonRequest personRequest)
{

How to use - Authorization summary

Specify [Authorization] headers on either a Controller:

[Authorize]
public class ValuesController : Controller

or on an action:

[Authorize("Customer")]
public PersonResponse GetPerson([FromBody]PersonRequest personRequest)

You can optionally specify policies [Authorize("Customer")] or roles [Authorize(Roles = "Customer")] and they will be added to the Summary too.

Pascal case or Camel case?

The default is camelCase. If you want PascalCase you can pass in a DefaultContractResolver like so: [SwaggerResponseExample(200, typeof(PersonResponseExample), typeof(DefaultContractResolver))]

The above is no longer supported - it will output Examples using whichever JSON serializer your controllers are configured with in services.AddControllers().

Minimal APIs

If you're using .NET 5 and above, we now default to use System.Text.Json.JsonSerializerDefaults.Web when rendering examples, which means you'll get camelCase. PascalCase is not supported.

Render Enums as strings

By default enums will output their integer values. If you want to output strings you can pass in a StringEnumConverter like so: [SwaggerResponseExample(200, typeof(PersonResponseExample), jsonConverter: typeof(StringEnumConverter))]

The above is no longer supported - it will output Examples using whichever JSON serializer your controllers are configured with in services.AddControllers().

Advanced: Examples with Dependency injection

If for some reason you need to have examples with DI (for example, to read them from a database), you can use constructor injection:

internal class PersonRequestExample : IExamplesProvider
{
    private readonly IHostingEnvironment _env;

    public PersonRequestExample(IHostingEnvironment env)
    {
        _env = env;
    }
    public object GetExamples()
    {
        return new PersonRequest { Age = 24, FirstName = _env.IsDevelopment() ? "Development" : "Production", Income = null };
    }
}

Then, you should register the Swagger examples via the extension methods:

services.AddSwaggerExamplesFromAssemblyOf<PersonRequestExample>();

or

services.AddSwaggerExamplesFromAssemblyOf(typeof(PersonRequestExample));

or

services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());

If you are using services.AddSwaggerExamples(), then you would have to manually register your IExamplesProvider class:

services.AddSingleton<PersonRequestExample>();

The FromAssemblyOf<T> extension method is the recommended approach.

swashbuckle.aspnetcore.filters's People

Contributors

0x53a avatar andrew-yustyk avatar bhugot avatar bigyellowhammer avatar buvinghausen avatar cumpsd avatar dependabot[bot] avatar dmitry-baryshev avatar dotdiego avatar icnocop avatar johnpudd avatar joseph51d avatar korifeich avatar lonix1 avatar mac2000 avatar matt-snyder-clear avatar mattfrear avatar penenkel avatar ron-macneil-youi avatar say25 avatar spottedmahn avatar stefan-z-camilleri avatar tomap avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swashbuckle.aspnetcore.filters's Issues

Enable support for other mime types besides application/json

I am using Swashbuckle.AspNetCore v2.4.0 and Swashbuckle.AspNetCore.Examples v 2.9.0.

As I understand the Open API v2.0 spec for examples, the examples should include the mime-type. Per ExamplesOperationFilter the mime type is being given as application/json.

This works for JSON responses; however, what if you have a response mime type of text/csv? The Open API spec link above has an example with two mime types: JSON and text.

I tried adding [Produces("text/csv")] to my action, as well as the attribute [SwaggerResponse(200, typeof(string))]. However it doesn't seem to pick up that mime type for the example.

Specifically, this is the swagger YAML:
example-json

This is how swagger-ui renders it:
example-swagger-ui-json

And this is what I would expect/want based off the Produces attribute:
example-text png

Is it possible to use a mime-type other than JSON? Thanks!

Feature Request: Retain Default Swashbuckle-Generated Values for Properties on Models Returned By Classes Extending IExamplesProvider When The Property Is Not Explicitly Set.

I have a fairly complex object, and there are about 12 properties among its several dozen that I need to have a default string value of "MMddyyyy" so AutoMapper doesn't blow up when my pipeline executes from SwaggerUI.

Until I found your library it was a pain to have to change 12 properties every time I wanted to execute one of my controller's pipelines that used this obj. Changing it once and saving the json in a txt file for copy pasting worked, but a code based fix via your library was even more ideal.

The problem though is when I set up my class extending the IExamplesProvider and return my model, I don't want to have to hand-write and initialize all 60ish properties on this beast even if it would be a one-and-done thing. Especially because I have several more models of comparable complexity that need the same one-off treatment for some but not all of their properties. All but the 12-or-so properties I care about were fine when Swashbuckle automatically set them to "string", or 0, or null, etc.

I want to just drill down to the 12 or so and set them. But right now by using the library this way the remainder of my top-level object will only hydrate based on what's in the constructors of its properties that are also classes. So a majority of my object loses its representation and is missing a multitude of properties that would have otherwise been equal to "string", 0, null, etc.

Is it possible to make it so that the default Swashbuckle model hydration occurs for the object, but then the properties I specify in my class extending IExamplesProvider will overwrite the specific values I've specified?

In this way my entire object would be hydrated programatically as it was before, but then the select properties I need to have unique non-default values would also be what I require.

This way I would only have to specify the values for the 12 properties I care about instead of having to manually lay out the entire beast of an object who's other properties were fine when their values were set to "string" or 0 by Swashbuckle.

Here is an example of two properties in my object from my Swashbuckle-generated json, when I do not use your library

{
  "OfficeId": "string",
  "TransactionOwner": {
    "FirstName": "string",
    "LastName": "string",
    "FullName": "string",
    "IdentificationNumber": "string",
    "PhoneNumber": [
      {
        "Type": 0,
        "CountryCode": "string",
        "Number": "string",
        "Extension": "string"
      }
    ],
    "EmailAddress": "string"
  },
  "SecondaryOwner": {
    "FirstName": "string",
    "LastName": "string",
    "FullName": "string",
    "IdentificationNumber": "string",
    "PhoneNumber": [
      {
        "Type": 0,
        "CountryCode": "string",
        "Number": "string",
        "Extension": "string"
      }
    ],
    "EmailAddress": "string"
  },

The Transaction Owner and Secondary Owner properties of my obj do not contain any of the properties that I need to have a specific value for. For that reason I did not instantiate these two properties and set any of their properties.

Because of this, this is the model I get back when I enable and use your library

  "TransactionOwner": {
    "PhoneNumber": []
  },
  "ManagedBy": 0,
  "TransactionApprover": {
    "PhoneNumber": []
  },

Display Enums with a description

Greetings :)

With the implementation of opt.DescribeAllEnumsAsStrings();, we can display an enumeration's string as below :

capture

With the enum declared like this :

public enum EnumTest
{
    [Description("This is the Food value")]
    Foo = 1,

    Bar = 2,

    Boo = 3
}

I would like to do two suggestions here :

  1. Being able to render the Description attribute, which works fine in class properties, but doesn't work for enums.
  2. When showing enum's strings, being able to still display the numeric value associated (1, 2 and 3 in this example). The reason why is that, in the case of what we are doing in the project I'm working on, ours consumers must enter a numeric value to make a choice (which corresponds to something in the Enum). We're looking for a way to associate the numeric value to a descriptive text, so the consumer knows which does what. We actually don't want him to send text.

Could it be something interesting enough to be implemented in a nearly future?

Thanks in advance :)

Support options.DescribeEnumsAsStrings

Swashbuckle has options

                c.DescribeAllEnumsAsStrings();
                c.DescribeAllParametersInCamelCase();
                c.DescribeStringEnumsInCamelCase();

We should support those instead of taking in serializer settings on the attributes

Exception when using ExampleFilters

Hi :)

I'm facing an exception when I'm using o.ExampleFilters().

This is the partial configuration code I have :

opt.ExampleFilters();
services.AddSwaggerExamples();

opt.OperationFilter<AddRequiredHeaderParameter>();
opt.OperationFilter<AddResponseHeadersFilter>();
opt.OperationFilter<DescriptionOperationFilter>();
opt.OperationFilter<AddFileParamTypesOperationFilter>();
opt.OperationFilter<AddResponseHeadersFilter>();
opt.DescribeAllEnumsAsStrings();
opt.DescribeAllParametersInCamelCase();

And this is the exception :

Application startup exception: System.InvalidOperationException: Unable to resolve service for type 'Swashbuckle.AspNetCore.Filters.RequestExample' while attempting to activate 'Swashbuckle.AspNetCore.Filters.ExamplesOperationFilter'.

   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.<>c__DisplayClass35_0`1.<CreateFilters>b__0(FilterDescriptor`1 descriptor)
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.CreateSwaggerGeneratorSettings(IServiceProvider serviceProvider)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.CreateSwaggerProvider(IServiceProvider serviceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6]
      Application startup exception
System.InvalidOperationException: Unable to resolve service for type 'Swashbuckle.AspNetCore.Filters.RequestExample' while attempting to activate 'Swashbuckle.AspNetCore.Filters.ExamplesOperationFilter'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.<>c__DisplayClass35_0`1.<CreateFilters>b__0(FilterDescriptor`1 descriptor)
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.CreateSwaggerGeneratorSettings(IServiceProvider serviceProvider)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.CreateSwaggerProvider(IServiceProvider serviceProvider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

We're using ASP.Net Core 2.0

Thanks in advance =)

no support for net462

Is there a reason for not supporting net462 in aspnetcore? When referencing the library, dotnet restore complains that netstandard1.3 is not compatible with net462.

SwaggerRequestExample always returns the same example

Hi,

I have decorated different actions in different controllers with:
[SwaggerRequestExample(typeof(JsonPatchDocument), typeof(PatchTypeOneExample))]

and
[SwaggerRequestExample(typeof(JsonPatchDocument), typeof(PatchTypeTwoExample))]

ie, the input type is the same - JsonPatchDocument, but the example values are quite different, because they are patching different types of resources.

In my swagger docs though I am seeing the PatchTypeOneExample for both.
Is this a bug in the code, or is there some way to override the behaviour?

thanks

DI

Not sure if that is an issue but will be nice if examples will be using built in DI

In our case we wish to be able to inject repo into example constructor and provide record right from db instead of hardcoding it

e.g. will be nice if there will be ability to write something like (pseudo code):

class ManagerExample implements Example {
    private readonly Repo _repo;
   ctor(repo);
   getExample => repo.findById(1);
}

Example for GET request query string parameters

Hello.

I have GET request with 2 query string parameters From and To. I created request example like:

public class RequestExample : IExamplesProvider<Request>
    {
        public Request GetExamples()
        {
            return new Request
            {
                From = "USD",
                To = "AUD"
            };
        }
    }

But I do not see this example in the swagger. Instead I only see 2 input fields in the UI. Is it possible to show request example for query params?

Thanks in advance!

SwaggerRequestExample same Request Object overrides previous one

Hello guys,
I'm using Swagger with c#, and here's an issue i'm currently facing, im using -
[SwaggerRequestExample(typeof(RequestType1),typeof(RequestType1Example))] and
[SwaggerRequestExample(typeof(RequestType1),typeof(RequestType2Example))] on two of my ActionMethods...

Where for example models are:

public class RequestType1{
  public int Id {get;set;}
  public int Name {get;set;}
  public int Surname {get;set;}
}
public class RequestType1Example : IExamplesProvider{
 public object GetExamples()
        {
            return new RequestType1
            {
                  Id = 1, 
                  Name = "Test Name"
            }
        }
}

public class RequestType1Example : IExamplesProvider{
 public object GetExamples()
        {
            return new RequestType1
            {
                  Id = 1, 
                  Surname = "Test Surname"
            }
        }
}

Problem is that in Swagger UI in both APIs - example is same.

Example Value : 
{
  "Id": "1",
  "Surname":"Test Surname"
}

Is there any workaround on this? Or could i specify some kind of attribute to make swagger show different examples for both APIs? Thanks in advance

Exception when DataMember specifies the name different from the property name.

If you have property in your model class marked like this:

[DataMember(Name="first")
public string FirstName { get; set; }

You will get the exception:

System.Collections.Generic.KeyNotFoundException occurred
  HResult=0x80131577
  Message=The given key was not present in the dictionary.
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Swashbuckle.AspNetCore.Examples.DescriptionOperationFilter.SetResponseModelDescriptions(Operation operation, ISchemaRegistry schemaRegistry, ApiDescription apiDescription) in D:\Work\GitHub\Swashbuckle.AspNetCore.Examples\src\Swashbuckle.AspNetCore.Examples\DescriptionOperationFilter.cs:line 49
   at Swashbuckle.AspNetCore.Examples.DescriptionOperationFilter.Apply(Operation operation, OperationFilterContext context) in D:\Work\GitHub\Swashbuckle.AspNetCore.Examples\src\Swashbuckle.AspNetCore.Examples\DescriptionOperationFilter.cs:line 19
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreateOperation(ApiDescription apiDescription, ISchemaRegistry schemaRegistry)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItem(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.<Invoke>d__6.MoveNext()

Not possible to create request examples for certain data types?

Isn't it possible to create request examples for certain types of body content? What I would like to create a request example for a controller method with the following signature:

[SwaggerRequestExample(typeof(Dictionary<string, object>), typeof(TestExampleDict))]
public async Task<IActionResult> TestMethod([FromBody]Dictionary<string, object> dictionary)

With an example class like this:

public class TestExampleDict : IExamplesProvider
{
    public object GetExamples()
    {
        return new Dictionary<string, object>
        {
            {"key1", 1 },
            {"key2", "string" },
            {"key3", true }
        };
    }
}

Th example just doesn't get created and when debugging, the GetExamples() method is never called.
Also, if I look at the generated JSON file, the examples for this type aren't listed.

I know that examples work per se in my project because I have some other controller methods where custom data types are passed in wih [FromBody] and my request examples for those methods work without a problem.

I also tried a few other things like not using type "object" or "Dictionary", etc but nothing worked.

Here's the alternatives I tried but where the request example didn't work as well:

  • Using Dictionary<string, string> instead of Dictionary<string, object>
  • Using Tuple<string, object> instead of Dictionary<string, object>
  • Using Tuple<string, string> instead of Dictionary<string, object>
  • Deriving my own type from Dictionary and using this as [FromBody] parameter: public class CustomDict : Dictionary<string, object>
//in seperate CustomDict.cs file
public class CustomDict : Dictionary<string, object> { }
..
//controller method in controller class
public async Task<IActionResult> TestMethod([FromBody]CustomDict dictionary)

The only thing that worked so far is wrapping the dictionary within a container class. In that case the example request works without a problem
Container class example:

public class DictionaryContainer
{
    public Dictionary<string, object> Dict;
}

ExampleProvider example:

public class TestExample: IExamplesProvider
{
    public object GetExamples()
    {
        var dict = new Dictionary<string, object>
        {
            {"IntVal", 13},
            {"BoolVal", true},
            {"GuidVal", Guid.Parse("1a0bdb34-a56a-439b-a8e6-6abd684dc817")}
        };

        return new DictionaryContainer {Dict = dict};
    }
}

Method signature example:

[SwaggerRequestExample(typeof(DictionaryContainer), typeof(TestExample))]
public async Task<IActionResult> TestMethod([FromBody]DictionaryContainer dictContainer)

In this case, the request example is generated and displayed without a problem. But although I can live with this workaround if I absolutely have too, I'd rather not because it's a bit ugly and makes the body content clients have to send unnecessarily complex. In this example

{
  "Dict": {
    "IntVal": 13,
    "BoolVal": true,
    "GuidVal": "1a0bdb34-a56a-439b-a8e6-6abd684dc817"
  }
}

Instead of just

{
  "IntVal": 13,
  "BoolVal": true,
  "GuidVal": "1a0bdb34-a56a-439b-a8e6-6abd684dc817"
}

So, I guess, my question is:
Am I doing something wrong? Or is there no native support for creating request examples for this kind of data type? If the latter's the case, is there any kind of workaround where I could get a simple body structure like the following and still use request examples?:

{
 "IntVal": 13,
 "BoolVal": true,
 "GuidVal": "1a0bdb34-a56a-439b-a8e6-6abd684dc817"
}

Thanks a lot in advance!

Incorrect JSON generated for a parameter example

We're getting warnings from ReDoc (e.g. Other properties are defined at the same level as $ref at "#/paths/~1quotes/post/parameters/0/schema". They are IGNORED according to the JsonSchema spec). Upon investigation, it looks like example for a parameter is added under schema, instead of next to schema, as per the specs (https://swagger.io/docs/specification/adding-examples/). Example that causes the warning:

    "/quotes": {
      "post": {
        "tags": ["Quotes"],
        "summary": "Create a new quote",
        "operationId": "CreateQuote",
        "consumes": ["application/json"],
        "produces": ["application/json"],
        "parameters": [{
          "name": "data",
          "in": "body",
          "required": false,
          "schema": {
            "$ref": "#/definitions/QuotingRequestValidated",
            "example": {
              "payment_type": "Provider",
              "country_code": "AU",
              "payment_destinations": [{
                  "payee_id": 10759,
                  "payer_amount": 10000.0
                },
                {
                  "payee_id": 163,
                  "payer_amount": 5000.0
                }
              ]
            }
          }
        }],
       "responses": {
       ...

Possibility to exclude media type from example

Current version of ExamplesOperationFilter always generate sample JSON with media type wrapper. Code already support possibility to generate pure example, but method FormatJson always called with parameter includeMediaType=true.
It would be nice to setup that option when we construct ExamplesOperationFilter
Thank you!

JsonPatchDocument Example

I have a simple patch endpoint and I'm trying to create an example:

[SwaggerRequestExample(typeof(JsonPatchDocument<UpdateCustomerRequest>), typeof(UpdateCustomerRequestExample))]
public IActionResult Patch(Guid id, [FromBody]JsonPatchDocument<UpdateCustomerRequest> updateCustomerRequestPatch)
public class UpdateCustomerRequestExample : IExamplesProvider
    {
        public object GetExamples()
        {
            return new JsonPatchDocument<UpdateCustomerRequest>()
            {
                Operations = { new Operation<UpdateCustomerRequest>("replace", "email", "[email protected]", "[email protected]") }
            };
        }
    }

Unfortunately the example displayed is:

[
  {
    "value": {},
    "path": "string",
    "op": "string",
    "from": "string"
  }
]

Media Type appearing in the UI for examples

Hi,

I'm using Swashbuckle.AstNetCore 1.0.0 with Swashbuckle.AspNetCore.Examples with version 2.1.1 of your package.

In the swagger UI I am seeing the media type as part of the model:

image

Which I wasn't expecting - is there a way to stop this happening

Support alternate media types

Currently a response example always uses the media type application/json. It would be useful to be able to specify alternate media types such as application/hal+json. The SwaggerResponseExampleAttribute could accept a content type parameter.

Happy to create a PR.

Null values in example are not included

Due to line 26 in the SerializerSettingsDuplicator, the response examples in the generator swagger definition are missing their null values in the example, while they should be there.

I've just tested it for in my project and it seems to work if I skip the linked Ignore assignment. The result is in the image below. If I do not skip the ignore line, the farm_uuid line would be missing (which is not desirable).

image

Except for the comment on the line, which seems to link to a somewhat unrelated issue (at least, it seems to me). When I check the swagger definition the following is generated, which seems perfectly fine to me:

{
  "responses": {
    "200": {
      "description": "Success",
      "schema": {
        "$ref": "#/definitions/Location"
      },
      "examples": {
        "application/json": {
          "uuid": "11111111-2222-3333-aaaa-bbbbbbbbbbbb",
          "location_type": "CowLocation",
          "location_name": "My Named Location 1",
          "location_number": 12345678,
          "capacity": 1000,
          "parent_uuid": "44444444-5555-6666-cccc-dddddddddddd",
          "farm_uuid": null,
          "iso_tag": 999000000000001
        }
      }
    }
  }
}

So, I'm not sure on why this is there, but I would like to remove it and use the actual settings used as used by the controller, in order to have a consistent definition.

Time to split up this project?

Hi,

The project is called "Swashbuckle.AspNetCore.Examples" and the purpose seems to be to enable you to generate swashbuckle examples...but now it lets you add an authorization input header box to your page, a file upload button, request headers (e.g. for correlation id) and now response headers too.

These are all very useful features to have, but have nothing at all to do with generating swashbuckle examples...so I wonder if it would make more sense to split that functionality off into a separate project and nuget package and keep Swashbuckle.AspNetCore.Examples purely for generating said swashbuckle examples?

SwaggerUI 3.0

Are there plans to udpate the SwaggerUI to 3.0? Or maybe it is and I'm not seeing the difference?

Question: How can I build urls inside an IExamplesProvider?

Hi,

We generate HAL links with our models and our examples include these links.
At the moment they are hard coded strings but that makes it very painful if we want to change a route, to remember everywhere we have an example to the old route.
It would be great if we could do a Url.Action(....) inside our example providers.
Is there a way to do this?

thanks

Any way to document url parameters?

Hi,

I have a url which would be something like /api/countries/USA/population/2017-09-02 where "USA" and "2017-09-02" are parameters to the action.
The date is only accepted in this very specific format and I would like to document this fact - is there any way to add a request example like this?

thanks

Does not work with ASP.NET Core 2

When using Swashbuckle.AspNetCore.Filters 3.0.2 with an ASP.NET Core 2 application, you get the following exception:

MissingMethodException:
Method not found: 'System.IServiceProvider Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection)'.

Swashbuckle.AspNetCore.Filters.SwaggerGenOptionsExtensions.AddSwaggerExamples(SwaggerGenOptions swaggerGenOptions, IServiceCollection services)

It would appear the issue is with the Microsoft.Extensions.DependencyInjection dependency (1.1.0) which made a breaking change to return ServiceProvider instead of IServiceProvider in the BuildServiceProvider() method.

SwaggerRequestExample should not have to match the type in method

I have a method that takes a generic JObject, so it's not really defined anywhere what the contents should look like and thus it's hard to get an example. However, I later map that JObject to a specific type. So I would like to set this type in the SwaggerRequestExample and have that appear in the example because that will mirror what my request body should look like. I am able to to this with Swashbuckle.Examples. However, a fatal error occurs in Swashbuckle.AspNetCore.Examples when I attempt the same thing.

My SwaggerRequestExample attribute:

[HttpPost]
[Route("api/ZipcodeGet")]
[SwaggerRequestExample(typeof(GetZipCodeRequest), typeof(DeliveryOptionsSearchModelExample))]
public IActionResult ZipcodeGet([FromBody] JObject request) => base.SendPost("ZipcodeGet", request);

My IExamplesProvider:

public class DeliveryOptionsSearchModelExample : IExamplesProvider
{
    public object GetExamples()
    {
        return new GetZipCodeRequest
        {
            zipCode = "37311"
        };
    }
}

swagger.json generation crashes when a controller operation accepts a nullable Enum as a parameter

Hello,

I wanted to use Swashbuckle.AspNetCore.Filters to extend the documentation of my WebAPI project and to provide sample requests/responses for faster manual testing via Swagger UI. However, I have encountered issues that I isolated, analysed and further explain below. It may be a bug, it may be a comprehension failure on my part. Hope I receive some help. :-)

Steps to reproduce

  1. Create a sample .NET Core WebAPI project.
  2. Add the following method to ValuesController class:
        // POST api/values/5
        [HttpPost("5")]
        public void NullableEnumTest(SomeEnum? someEnum)
        {
        }

and the following anywhere else:

    public enum SomeEnum
    {
        SomeEnumValue,
        AnotherEnumValue
    }
  1. Install Swashbuckle.AspNetCore and Swashbuckle.AspNetCore.Filters NuGet packages and configure them as per their doc entries.
  2. Start the application, navigate to swagger.json URL.

Expected result
swagger.json file is presented in its full glory.

Actual result
A WebAPI Development error page opens, with ArgumentException and TypeLoadException exceptions linked to attempting to instantiate an IExamplesProvider instance for a nullable enum type.
https://ibb.co/fArcB8

Allow inherited attributes

Thanks for all the work here showing us how to add swagger examples!

I tried to create a new attribute that inherits from SwaggerRequestExampleAttribute allowing me to specify just the type of the request parameter and always use a generic for constructing the example. The generic implements IExamplesProvider and looks in the assemblies for classes that implement an interface (ISampleData) to provide the sample data.

e.g.

[RequestSampleData(typeof(MyClass))]
public class RequestSampleDataAttribute : SwaggerRequestExampleAttribute
    {
        public RequestSampleDataAttribute(Type requestType) :
            base(requestType, typeof(SampleData.SampleDataGenerator<>).MakeGenericType(requestType))
        {
        }
    }

This did not work. I believe the reason is this line in ExamplesOperationFilter:

var swaggerRequestAttributes = actionAttributes.Where(r => r.GetType() == typeof(SwaggerRequestExampleAttribute));

I think if this check was modified to check for anything assignable to SwaggerRequestExampleAttribute then it would have worked?

Does this make sense or should I have approached this in a different way?

Ultimately I would like to create an operation filter that looked at the parameters, automatically looked for any class implementing my ISampleData interface for the class and then added examples for them. Have you considered extending the functionality so we could use the library to add examples to the schema from our own operation filters? (or is it already there and I did not see it!)

Package needs update for Swashbuckle 4

I now run in following exception on startup:

MissingMethodException: Method not found: 'Void Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenOptions.OperationFilter(System.Object[])'.
Swashbuckle.AspNetCore.Filters.SwaggerGenOptionsExtensions.ExampleFilters(SwaggerGenOptions swaggerGenOptions)
MyProject.Startup.b__20_0(SwaggerGenOptions configuration) in Startup.cs
Microsoft.Extensions.Options.ConfigureNamedOptions.Configure(string name, TOptions options)
Microsoft.Extensions.Options.OptionsFactory.Create(string name)
System.Lazy.CreateValue()
System.Lazy.LazyInitValue()
Swashbuckle.AspNetCore.SwaggerGen.ConfigureSchemaRegistryOptions..ctor(IServiceProvider serviceProvider, IOptions swaggerGenOptionsAccessor)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope scope)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.GetService(IServiceProvider sp, Type type, Type middleware)
lambda_method(Closure , object , HttpContext , IServiceProvider )
MyProject.SwaggerAuthorizedMiddleware.Invoke(HttpContext context) in SwaggerAuthorizedMiddleware.cs
Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Error responses not appearing in UI

Hi,

I am not seeing my error response examples in the swashbuckle UI.
I downloaded your repo and tried with your examples and get the same thing:

image

ie, the defaults for error responses are being returned.

SwaggerRequestExample and array (Or List<T>)

Hi

Maybe I'm doing this wrong but i can't get my code to work, this is a method in my controller

[SwaggerRequestExample(typeof(NewOrderDto), typeof(NewOrderListExample))]
public async Task<IActionResult> AddOrderAsync([FromBody] List<NewOrderDto> orders)

My Example class returns this:

return new List<NewOrderDto>
{
    new NewOrderDto
    {
        Foo= "bla"
    },
    new NewOrderDto
    {
        Foo= "bla2"
    }
};

With that code, the request example object its just an object with default values, if i change the method to public async Task<IActionResult> AddOrderAsync([FromBody] NewOrderDto orders) the example its added to the documentation.

I debugged the code in ExamplesOperationFilter with List as the parameter and the validation fails here:

var request = bodyParameters.FirstOrDefault(p => p.Schema.Ref == schema.Ref);
if (request != null) /// does not enter here because  p.Schema.Ref  == null

I modified the class to enter another path when ExamplesProviderType is my type, but in that case, the example returned its a nested array [ [ { "foo": "bla" }, { "foo": "bla2" } ] ]

Its my input parameter wrong or I'm not decorating right my method?

Thanks a lot for your time

Additional response examples are not honoured

Hi

First of all, thank you for your great library.

In my case, I've been working with this and even modified it a bit. Yet either I am doing something wrong, or I don't know, but examples for additional responses are not being generated for me.

I am using v2.1.1

screen shot 2017-08-13 at 09 13 42

To the left is the minor modification I made to your library, which simply swaps out the StatusCode with a version that has a descriptive version (ex. (200) OK).

As you can see from the screenshot, the examples are being provided using default values... yet whilst debugging the IOperationFilter I can clearly see the example set correctly on the Response.Examples object.

p.s. this works fine for the request body.

Additional info

The action
screen shot 2017-08-13 at 09 16 08

One of the examples that is not output
screen shot 2017-08-13 at 09 18 18

The example is clearly there during debug
screen shot 2017-08-13 at 09 22 05

What am I missing?

The example attribute can't actually act on Controller Action

Hi :
I have a issue , in my code , it has two function use the same models, and i want to provide different example for both of them, like follow code :

public class DemoController : Controller {
  [SwaggerRequestExample(typeof(DemoModel ), typeof(ExampleOne))]
  public void ActionOne (DemoModel input){
    // do something
  }

  [SwaggerRequestExample(typeof(DemoModel ), typeof(ExampleTwo))]
  public void ActionTwo (DemoModel input){
    // do something
  }
}

public class DemoModel  {
  public string Name {get; set;}
}

public class ExampleOne : IExamplesProvider {
  public object GetExamples(){
    return new{
      Name = "Example One"
    }
}

public class ExampleTwo : IExamplesProvider {
  public object GetExamples(){
    return new{
      Name = "Example Two"
    }
}

I expect it show "Example One" on ActionOne example , and "Example Two" on ActionTwo example

However it both show "Example Two" in fact.

Strong naming Scrutor dependency issue with full .Net framework application

When using the .AddSwaggerExamplesFromAssemblyOf<>() method in ConfigureServices() for an ASP.NET core application targeting the full .NET framework we receive the following runtime exception:

System.IO.FileLoadException
HResult=0x80131044
Message=Could not load file or assembly 'Scrutor, Version=2.2.2.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
Source=Swashbuckle.AspNetCore.Filters
StackTrace:
at Swashbuckle.AspNetCore.Filters.ServiceCollectionExtensions.AddSwaggerExamplesFromAssemblyOf[T](IServiceCollection services)
at WebApplication1.Startup.ConfigureServices(IServiceCollection services) in ...\WebApplication1\Startup.cs:line 39

This does not occur when targeting .NET core. Adding swagger and the filters package to a new Web API project using the VStudio templates results in a project like so:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net47</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.2" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
    <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="4.2.0" />
  </ItemGroup>

</Project>

This project will throw the error during startup, but changing the TargetFramework to netcoreapp2.1 will succeed.

I noticed on the Scrutor page that you requested a new version from the author that is strongly signed which he added in his version 3.0.0. I thought I would submit a quick PR to update the dependency version, but his v3.0.0 targets .net standard 2.0 which conflicts with the .net standard 1.6 that this project currently targets.

I know a lot has been written about the pros and cons of strongly signing assemblies in nuget packages which I don't want to rehash, but if it's not simple to update the dependency on Scrutor, perhaps you could support signed and unsigned versions of this package?

Cheers,
Aaron

Description not working for Arrays

Hi,

I'm using the Description attribute in the models that are part of response or request data.
Unfortunately, if I declare in the root model an Array of a class that has the Description attributes, those are not rendered in the Swagger.json.

Here is a sample :

    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        [HttpPost]
        public void Post([FromBody]RootModel value)
        {
        }
    }

    public class RootModel
    {
        [Description("This ROOT description works")]
        public SubModelA SubModelA { get; set; }

        [Description("This ROOT description works")]
        public SubModelB[] subModelBs { get; set; }
    }

    public class SubModelA
    {
        [Description("This description works")]
        public string A { get; set; }
    }

    public class SubModelB
    {
        [Description("This description DOESN'T work")]
        public string B { get; set; }
    }

And here is the render :

capture

Thanks =)

Values are not set in UI for multiple SwaggerResponseExample-s

For instance this line states:
[SwaggerResponseExample(404, typeof(NotFoundResponseExample))]

NotFoundResponseExample initializes errorCode with 404 value. But Example Value in Swagger UI for test WebAPI project shows the default value for integer - 0.

Operation handling SwaggerResponseExample attribute should handle all attributes rather than only those which have the same response type as API action.

@mattfrear please consider to fix.

Enable custom JSON serialization

I need my example properties to be in PascalCase, and my enums to be rendered as strings.

Ideally this would be done with a service collection.

Each object can only has one example?

I have two APIs which they both take in the same object. However , I need different examples for each object.
So what I have done is:

    [Route("ca/student/add")]
    [HttpPost]
    [SwaggerRequestExample(typeof(STUDENT), typeof(AddStudentExample))]
    public IHttpActionResult AddStudentRecord(STUDENT student)
    {
        return Ok(this._projectService.AddStudentData(student));
    }

    [Route("ca/student/update")]
    [HttpPost]
    [SwaggerRequestExample(typeof(STUDENT), typeof(UpdateStudentExample))]
    public IHttpActionResult UpdateStudentRecord(STUDENT student)
    {
        return Ok(this._projectService.UpdateStudentData(student));
    }

So I have created two different class as AddStudentExample and UpdateStudentExample
In each class the GetExamples() is returning a STUDENT object with different values.
But in the swagger, the example values shown for both of these two APIs are the value of UpdateStudentExample.
Is it possible for me to make these two APIs have different examples?
Thank you.

Switch to use ProducesResponseType instead of SwaggerResponse

Swashbuckkle.AspNetCore has moved away from SwaggerResponse annotation. As described
here, we should be using ProducesResponseType instead, which I think is a cleaner approach as it removes the direct dependency of the API dll on Swashbuckle. I am wondering if/when this will be incorporated in here. Thanks.

Readme refers to SwaggerResponse attributes

In Readme there are examples of SwaggerResponse

[SwaggerResponse(200, Type=typeof(IEnumerable<Country>))]
[SwaggerResponseExample(200, typeof(CountryExamples))]
[SwaggerResponse(400, Type = typeof(IEnumerable<ErrorResource>))]
public async Task<HttpResponseMessage> Get(string lang)

However "As of beta902, SwaggerResponse attributes have been removed in favor of the built in ProducesResponseType attributes."
From domaindrivendev/Swashbuckle.AspNetCore#49

Please update the document

Support SwaggerResponseExample at controller level?

Hello,

Currently, SwaggerResponseExample attribute works only on methods (actions). Anyhow, if I would like to provide response examples for HTTP errors, that means I have to add the following duplicate code for every single action within a controller:

[SwaggerResponseExample(StatusCodes.Status404NotFound, typeof(NotFoundErrorExample))]
[SwaggerResponseExample(StatusCodes.Status400BadRequest, typeof(BadRequestErrorExample))]
[SwaggerResponseExample(StatusCodes.Status401Unauthorized, typeof(UnauthorizedErrorExample))]
[SwaggerResponseExample(StatusCodes.Status403Forbidden, typeof(ForbiddenErrorExample))]

As any of the methods within a controller might return these responses, would it be possible to support them per controller (class) level? In that case, they could be automatically applied to all the actions, merging them with any per-action response examples?

This would also allow to be aligned with the way ProducesResponseType attribute works, at I currently can use it on a controller to define common response types (e.g. for 404) for all actions, as well as have it set per action for individual response types (e.g. for 200).

Maybe I'm not aware and there's another practice to define common responses with examples?

Thank you.

DescribeAllEnumsAsStrings Support

I'm using DescribeAllEnumsAsStrings and I can't get that working w/ SwaggerRequestExample.

Before adding Swashbuckle.AspNetCore.Filters

{
  "Id": "string",
  "Name": "string",
  "Status": "Active"
}

After adding Swashbuckle.AspNetCore.Filters

public class MyModelExample : IExamplesProvider
{
	public object GetExamples()
	{
		return new MyModel
		{
			Name = "A Test",
			Status = MyStatus.Active,
			ThirdPartyId = "100"
		};
	}
}
{
  "ThirdPartyId": "100",
  "Name": "A Test",
  "Status": 0
}

Thoughts? ๐Ÿ’ญ Thanks ๐Ÿ™!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.