Generating Swagger example requests with Swashbuckle

This is a follow on from my post from last year about Generating example Swagger responses.

Update April 2020: You probably don’t need to do it this way any more. Swashbuckle.AspNetCore supports request examples via XML comments. See my blog post.

Update May 4th 2017: I have created a new NuGet package called Swashbuckle.Examples which contains the functionality I previously described in this blog post. The code lives on GitHub.

I have also created a .NET Standard version of the NuGet package at Swashbuckle.AspNetCore.Filters, which is also on GitHub.

It can also be useful to generate example requests, and in this post I will show you how.

First, install my Swashbuckle.Examples NuGet package, or the .NET Core version Swashbuckle.AspNetCore.Filters

Now decorate your controller methods with the included SwaggerRequestExample attribute:

[Route(RouteTemplates.DeliveryOptionsSearchByAddress)]
[SwaggerRequestExample(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(DeliveryOptionsModel), Description = "Delivery options for the country found and returned successfully")]
[SwaggerResponseExample(tHttpStatusCode.OK, typeof(DeliveryOptionsModelExample))]
[SwaggerResponse(HttpStatusCode.BadRequest, Type = typeof(ErrorsModel), Description = "An invalid or missing input parameter will result in a bad request")]
[SwaggerResponse(HttpStatusCode.InternalServerError, Type = typeof(ErrorsModel), Description = "An unexpected error occurred, should not return sensitive information")]
public async Task<IHttpActionResult> DeliveryOptionsForAddress(DeliveryOptionsSearchModel search)
{

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

public class DeliveryOptionsSearchModelExample : IExamplesProvider
{
    public object 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" }
                }
            }
        };
    }

Don’t forget to enable the ExamplesOperationFilter when you enable Swagger, as before:

configuration
    .EnableSwagger(c =>
    {
        c.OperationFilter<ExamplesOperationFilter>();
    })
    .EnableSwaggerUi();

Or if you’re using .NET Core

services.AddSwaggerGen(c =>
   {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
        c.OperationFilter<ExamplesOperationFilter>();

Now that we’ve done all that, we should see the examples output in our swagger.json file, which you can get to by starting your solution and navigating to /swagger/docs/v1.

Capture

And the best part is, when you’re using swagger-ui (at /swagger/ui/index), now when you click the example request in order to populate the form, instead of getting an autogenerated request like this:

Untitled

You’ll get your desired example, like this:

Capture2

I find that having a valid request on hand is useful for smoke testing your API endpoints are working correctly.

72 thoughts on “Generating Swagger example requests with Swashbuckle

  1. line 38 of SetResponseModelExamples
    should be
    var responseAttributes = apiDescription.GetControllerAndActionAttributes();

    of you could rename SwaggerRequestExamplesAttribute class to SwaggerResponseExamplesAttribute, which is what I did when implementing your sample

    thanks again.

  2. Great article! And of course, a question:

    I have an API with a polymorphic service endpoint: /api/v1/vehicles. The endpoint accepts a parameter of type Vehicle, which is an abstract class with shared vehicle properties and a VehicleType enumeration property (enumeration values of Car, Truck, ..). Internally, the API uses a JsonConverter class to resolve the concrete Vehicle based on the VehicleType property that is passed in.

    The Swashbuckle documentation shows the Vehicle schema as my input parameter, but I would like to replace it with examples of the various concrete Vehicles that can be passed in. Using the pattern you describe in this post produces a run-time javascript/swagger exception. I assume it’s because the abstract Vehicle and concrete classes have different schemas. Any idea on whether it is possible to do what I want to do, or if there is a better solution for my problem?

    Thanks in advance.

    • I wouldn’t expect that to be an issue – I’m not the author of SwaggerResponse but I would think you should be able to specify the typeof one of your concrete classes as the Type parameter and it would be happy. Did you try that?

      Maybe ask your question in the Swashbuckle github page.

      • Matt, thanks for your response. Using typeof of my concrete class in the attribute declaration does not work because my concrete class does not implement IExampleProvider. The issue is in the schema replacement. As far as support from swashbuckle, the package doesn’t offer official support for documenting polymorphic endpoints (https://github.com/domaindrivendev/Swashbuckle/issues/313), so I may have to change my implementation.

  3. Thanks, Are you able to update example to latest version (6.0.0-beta902) it looks like IOperationFilter has changed since this article was posted.

    Thanks again

      • Hi Matt,

        Could you please help me out in implementing default request data to the controller action of the model schema on the Swagger UI with Swagger 6.0.0-rc1-final with C#, same like your above implementation. As i’m using Swagger 6.0.0-rc1-final the functions which are used at above link are not found in this swagger which i’m using.

      • Sorry Kumar, but I haven’t looked at Swashbuckle 6 – my work project is on Swashbuckle 5 and it works, so I’m not likely to upgrade it if there’s breaking changes. If you need support you could try posting an issue on the Swashbuckle github. Alas I don’t have any spare time to play around with this outside of work.

  4. Hi Matt,

    Thank you for the example, very useful.

    For me to get it working I used Newtonsoft.Json (otherwise the Swagger UI show nothing)

    Newtonsoft.Json.JsonConvert.SerializeObject(provider.GetExamples(), Formatting.Indented);
    // ((dynamic)FormatAsJson(provider))[“application/json”];

    and also had to comment out some parts of the following

    var response =
    operation.responses.FirstOrDefault(
    x => x.Value != null); // && x.Value.schema.@ref == schema.@ref && x.Value.schema != null); //

    Any idea what I might be missing?

    Thanks,
    Gavin

    Full code below.

    private static void SetRequestModelExamples(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
    var requestAttributes = apiDescription.GetControllerAndActionAttributes();

    foreach (var attr in requestAttributes)
    {
    var schema = schemaRegistry.GetOrRegister(attr.ResponseType);

    var request = operation.parameters.FirstOrDefault(p => p.@in == “body” && p.schema.@ref == schema.@ref);

    if (request != null)
    {
    var provider = (IProvideExamples)Activator.CreateInstance(attr.ExamplesType);

    var parts = schema.@ref.Split(‘/’);
    var name = parts.Last();

    var definitionToUpdate = schemaRegistry.Definitions[name];

    if (definitionToUpdate != null)
    {
    definitionToUpdate.example = Newtonsoft.Json.JsonConvert.SerializeObject(provider.GetExamples(), Formatting.Indented);
    // ((dynamic)FormatAsJson(provider))[“application/json”];

    }
    }
    }
    }
    private static void SetResponseModelExamples(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
    var responseAttributes = apiDescription.GetControllerAndActionAttributes();

    foreach (var attr in responseAttributes)
    {
    var schema = schemaRegistry.GetOrRegister(attr.ResponseType);

    var response =
    operation.responses.FirstOrDefault(
    x => x.Value != null); // && x.Value.schema.@ref == schema.@ref && x.Value.schema != null); //

    if (response.Equals(default(KeyValuePair)) == false)
    {
    if (response.Value != null)
    {
    var provider = (IProvideExamples)Activator.CreateInstance(attr.ExamplesType);
    response.Value.examples = FormatAsJson(provider);
    }
    }
    }
    }

    • I think if you had to comment out that line to get it to work, then you haven’t defined the [SwaggerRequestExamples] attribute above your controller’s method, like I do above:

      [SwaggerRequestExamples(typeof(DeliveryOptionsSearchModel), typeof(DeliveryOptionsSearchModelExample))]

  5. Excelent post! Very useful.
    Just one question about the displayed screen capture. How do you get the Authorization (access token) input field?
    Is it some customization?

    Thanks!

  6. Is it possible to manage multiple default values when the endpoint request model has more than one parameter?

    i.e.:
    public async Task GetDocument (RequestBase request, int Id)

    Can I post default values for request object, but also for Id ?

    How can I handle this…?

    Thanks

    • C# allows you to pass default parameters at compile time so you should be able to do:
      public async Task GetDocument (RequestBase request, int id = 3)

      To set defaults on your RequestBase object, you could do it a number of ways. The easiest place is on the RequestBase’s constructor.

      Another way would be to have a static “default” RequestBase object and set it to that in your controller action method. e.g.
      public async Task GetDocument (RequestBase request = null, int id = 3)
      {
      request = request ?? DefaultRequestBase;
      }

      Another way would be to take advantage of ASP.NET’s model binding and explicitly pass through the RequestBase’s properties to your controller action and default them there e.g. assuming your RequestBase looks something like this:
      public class RequestBase
      {
      public int Blah { get; set; }
      }

      public async Task GetDocument (int blah = 7, int id = 3)

      My favourite approach is another way – have a specific GetDocument request object which inherits from RequestBase and use that in your action method. Then have the default values in the GetDocumentRequest constructor.

      public async Task GetDocument (GetDocumentRequest documentRequest)

      • Thanks! I think I didn’t explain myself correctly.

        What I need to know if it’s possible is how can I define a the decorator SwaggerRequestExamples when I have more than one parameter in my endpoint.

        i.e.:
        [SwaggerRequestExamples(typeof(RequestBase), typeof(RequestBaseExamples))]
        public async Task GetDocument (RequestBase request, int Id)

        In this case, I can implement the GetExamples method for RequestBase class, but I can’t define the example value for Id parameter.

        Did I explain my self this time?

        Thanks again!

      • Oh, OK. You should be able to define the attribute multiple times:

        [SwaggerRequestExamples(typeof(RequestBase), typeof(RequestBaseExamples))]
        [SwaggerRequestExamples(typeof(int), typeof(IntExample))]
        public async Task GetDocument (RequestBase request, int Id)

        But I think it would be better to create a specific GetDocumentRequest object which inherits your RequestBase.
        [SwaggerRequestExamples(typeof(GetDocumentRequest), typeof(GetDocumentRequestExample))]
        public async Task GetDocument (GetDocumentRequest request)

      • Thanks mattfrear!
        I tried with the first approach. But it doesn’t work. It says:
        Duplicate ‘SwaggerRequestExamples’ attribute. I think it’s not possible.

        The thing with your 2nd approach, is that my endpoint has some body parameters (RequestBase) and some uri parameters (Id). That’s why I don’t have all the endpoint parameters encapsulated in a single class inheriting RequestBase.

        Do you think is it possible to decorate my endpoint in such a way it would be possible to define default values for my request parameters?

        Thanks again!

      • Nope – you can’t define default values for a query string request parameter.

        My ExamplesOperationFilter populates the “example” property of a schema object in the swagger json.

        Thus in order to have an “example” a parameter must have a “schema” property.

        The swagger spec at http://swagger.io/specification/#parameterObject states that the schema property can only be set if the “in” of a parameter is “body” (i.e. not “query”).

        Thus what you’re trying to do can’t be done, according to the swagger spec

  7. Hi Matt!
    Thanks for the answer.
    Do you know alternative where I can store comments for Response messages? Is it ok to store this in implementation notes ? How developers of Swash solve this problem of commenting ?
    Vitaly

    • I just did a bit of digging through the swagger spec, and what you need to do is supported, by adding a “description” property to the definition. I couldn’t actually see this in the swagger spec but if you look at the swagger petstore example (http://editor.swagger.io/) and search for “pet status in the store” you will see it in the example .yaml. You can use the File menu in that editor to download the swagger.json and then see the descripton there.

      I haven’t got time right now to implement this but it should be a simple modification to my ExamplesOperationFilter to add the description property. You could probably set a [Description] attribute on each property and read that in the ExamplesOperationFilter.

      I’ll have a look at doing this for you in the next week. No guarantees though – as I say it should be simple to implement if you want to do it.

      • Vitaly – I have implemented this for you.

        1. Pull down the latest version of the NuGet package
        2. Register the new DescriptionOperationFilter – c.OperationFilter();
        3. Add a [Description(“this is a description”)] attribute to your response model

        Then in the swagger.json, you should see the description field populated, e.g:
        “PersonResponse”: {
        “type”: “object”,
        “properties”: {
        “id”: {
        “format”: “int32”,
        “type”: “integer”
        },
        “firstName”: {
        “description”: “The first name of the person”,
        “type”: “string”
        },

  8. I had a similar issue to what was noted earlier. There was no swagger UI unless I changed the code slightly for the request example:

    if (definitionToUpdate != null)
    {
    //definitionToUpdate.Example = ((dynamic)FormatAsJson(provider))[“application/json”];
    definitionToUpdate.Example = Newtonsoft.Json.JsonConvert.SerializeObject(provider.GetExamples(), Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
    }

    The difference is with dynamic, the example in swagger.json is an object:
    “example”: {
    “companyId”: “6090511f-50d9-44b0-a657-f2c4a697f6ff”,
    “name”: “ABC Co.”,
    “internalId”: null
    }

    And with the JsonConvert the result is a string:
    “example”: “{\r\n \”CompanyId\”: \”6090511f-50d9-44b0-a657-f2c4a697f6ff\”,\r\n \”Name\”: \”ABC Co.\”,\r\n \”InternalId\”: null\r\n}”

    I assume the correct result is a string to display in the box in the UI?. I’m using the ASP.NET core library.

    Thank you

    • Hi hubbins,

      Thanks for your notes. The swagger spec is loose as to what an “example” can be:
      http://swagger.io/specification/#schemaObject
      It says: “example Any A free-form property to include an example of an instance for this schema.”

      So it appears we are both correct.

      I implemented it so that an example is a JSON object, and that works fine for me – as per the screenshot in my blog post, swagger-ui “Model Schema” box is populated, and when clicked the example request gets copied into the request parameter.

      I’m interested to know why it’s not working for you. If you have time, could you create an issue on the GitHub page (ideally with some repro steps).

      Thanks

      • The issue was returning a null for a value in the request sample, this would result in a client-side parsing error. In my sample request, there are several optional values, instead of rendering them with a value of null, now they are omitted. It would be better to show them with null, but I think there’s some disagreement about that in the spec.

        “Uncaught TypeError: Swagger 2.0 does not support null types ([object Object]). See https://github.com/swagger-api/swagger-spec/issues/229

        I added “Ignore” for null value handling here and it resolved the issue. I’m not sure this is correct with regard to the spec, though.

        private static object ConvertToCamelCase(Dictionary examples)
        {
        var jsonString = JsonConvert.SerializeObject(examples, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore });
        return JsonConvert.DeserializeObject(jsonString);
        }

      • Thanks for the reply. I have had a play, and have implemented your NullValueHandling fix for the request examples. It seems to work fine with the (dynamic) casting so I have left that in instead of returning the example as a string.

        The code is updated in GitHub, and I have published a new version of the NuGet packages.

        Have a play, and let me know if you have any problems.

        Thanks

  9. I use the SwaggerRequestExampleAttribute with a List. If I try to load the swagger page I get an NullReferenceException. If I use a None List-Class it’s works.

    • Hi,
      Could you please help me with the sorting of the example request body generated in swagger.

      • Sorting as in the the XML request body the swagger generates from the webapi…I need that to be in alphabetical order that is I want to change the order of the XML schema parameters.

      • The swagger generates this XML schema but in order for data contract deserialser to deserialise it it should be in alphabetical order.

        test123
        test123
        bf8195f9-caf5-460d-b7a6-d23d6c9e1904
        7

  10. Hi,
    first of all thanks for the library.
    I have trouble defining a sample request with an integer parameter in a get, I do not see the example that I create, which instead with a complex object as input parameter of another post method I can see.
    it is possible set sample request for simple type for example int or string, or it works only with complex obect?

  11. Hi Matt and thanks for the library!

    I have an issue, when including an example (like the one shown) in the following. The swagger.json validates fine, but the Swagger UI gets stuck at ‘fetching resource list…’. Examples for other classes works fine. Any ideas?

    “PrivateCustomer”: {
    “description”: “Model documentation for Customer”,
    “required”: [
    “firstName”,
    “lastName”,
    “street”,
    “streetNumber”,
    “postArea”,
    “countryCode”,
    “clubId”
    ],
    “type”: “object”,
    “properties”: {
    “customerNumber”: {
    “format”: “int32”,
    “description”: “Customer number.”,
    “type”: “integer”
    },
    “firstName”: {
    “description”: “Forename or first name.”,
    “type”: “string”
    },
    “lastName”: {
    “description”: “Surname.”,
    “type”: “string”
    },
    “cpr”: {
    “description”: “The CPR code of the private customer.”,
    “type”: “string”
    },
    “birthDate”: {
    “format”: “date-time”,
    “description”: “The date of birth of the private customer.”,
    “type”: “string”
    },
    “street”: {
    “description”: “The street name in the address.”,
    “type”: “string”
    },
    “streetNumber”: {
    “description”: “The street number of the adress.”,
    “type”: “string”
    },
    “floor”: {
    “description”: “The floor of the adress.”,
    “type”: “string”
    },
    “floorExt”: {
    “description”: “The door number of the adress, left/right etc.”,
    “type”: “string”
    },
    “placeName”: {
    “description”: “The place name of the address.”,
    “type”: “string”
    },
    “postArea”: {
    “description”: “The city part of the post code in the address.”,
    “type”: “string”
    },
    “city”: {
    “description”: “The town or city in the address.”,
    “type”: “string”
    },
    “country”: {
    “description”: “The country part of the post code in the address.”,
    “type”: “string”
    },
    “countryCode”: {
    “description”: “The country code the address. Typically ‘DK'”,
    “type”: “string”
    },
    “clubId”: {
    “format”: “double”,
    “description”: “The customernumber of the club to which the customer belongs.”,
    “type”: “number”
    },
    “phoneNumber”: {
    “description”: “The phonenumber of the customer.”,
    “type”: “string”
    },
    “mobileNumber”: {
    “description”: “The mobilenumber of the customer.”,
    “type”: “string”
    },
    “emailAddress”: {
    “description”: “The emailaddress of the customer.”,
    “type”: “string”
    },
    “website”: {
    “description”: “The website of the customer.”,
    “type”: “string”
    },
    “newsletter”: {
    “description”: “Customer subscribes to newsletter.”,
    “type”: “boolean”
    },
    “eBoks”: {
    “description”: “Customer subscribes to e-Boks.”,
    “type”: “boolean”
    }
    },
    “example”: {
    “customerNumber”: 0,
    “firstName”: “Arne”,
    “lastName”: “Mello”,
    “cpr”: null,
    “birthDate”: “1967-11-28T09:14:08.9666575+01:00”,
    “street”: “Bøgevej”,
    “streetNumber”: “12”,
    “floor”: “3”,
    “floorExt”: “th”,
    “placeName”: “Østerby”,
    “postArea”: “9000”,
    “city”: “Aalborg”,
    “country”: “Danmark”,
    “countryCode”: “DK”,
    “clubId”: 123456.0,
    “phoneNumber”: “12345678”,
    “mobileNumber”: “87654321”,
    “emailAddress”: “my@mail.dk”,
    “website”: “my_site.dk”,
    “newsletter”: false,
    “eBoks”: true
    }
    }

  12. Hey Matt,
    Nice work. Does this support multiple examples for the same method, like:
    [SwaggerRequestExample(typeof(ObjectRequestStyle1), typeof(object1))]
    [SwaggerRequestExample(typeof(ObjectRequestStyle2), typeof(object1))]
    or an IEnumerable of Types?

    • Nope, you can only have one Request example.

      Yes, IEnumerable is supported but you have to get the syntax just right. See the Readme on the Github page (regarding List).

  13. Hi, just FYI, the bit where you have to add the OperationFilter – for .Net Core 2, I had to add it inside the “AddSwaggerGen( )” delegate, instead of the “EnableSwagger( )” as shown in the example. e.g:

    services.AddSwaggerGen(options => { options.OperationFilter( ); });

  14. I hope that this doesn’t sound obvious or trivial.
    The web api is .net core.
    I’ve added c.OperationFilter(); to the services.AddSwaggerGen implementation in the Startup.ConfigureServices.
    The api has a series of Get UIs that all expect a single string parameter called “id”.

    [HttpGet(“User/{id}”)]
    [MobileExceptionFilter]
    [SwaggerRequestExample(typeof(string), typeof(GetUserModelExample))]
    [SwaggerResponse((int)HttpStatusCode.OK, “Returns the detailed response for the user”, typeof(MobileUser))]
    public async Task GetUser(string id)
    {

    Each example will be different for each of UI endpoints.

    One example is:

    using Swashbuckle.AspNetCore.Examples;

    namespace Strata.Mobile.Service.Examples
    {
    public class GetUserModelExample : IExamplesProvider
    {
    public object GetExamples()
    {
    return “10101010-1111-0000-1111-101010101010”;
    }
    }

    }

    However, when I look at the Swagger UI, no example is displayed.

  15. Hi Matt,

    I have a class that implements IExampleProvider. Is it possible to return an instance of a class, depending on some version if have configured in my .net core application?

    services.AddScoped();

    I want to do something like this:

    public class MyExample : IExamplesProvider
    {
    private readonly IRelease _someRelease;

    public MyExample(IRelease someRelease)
    {
    _someRelease = someRelease;
    }

    public object GetExamples()
    {
    if (_someRelease.Version == 1) return new { Version = 1 }
    if (_someRelease.Version == 2) return new { Version = 2 }
    }
    }

    I get the following error when trying to ‘inject’ IRelease into the example class.

    “No parameterless constructor defined for this object.”

    Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware|ERROR| An unhandled exception has occurred while executing the request System.MissingMethodException: No parameterless constructor defined for this object.
    at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
    at System.Activator.CreateInstance(Type type, Boolean nonPublic)
    at System.Activator.CreateInstance(Type type)
    at Swashbuckle.AspNetCore.Examples.ExamplesOperationFilter.ExamplesProvider(IServiceProvider services, Type examplesProviderType)
    at Swashbuckle.AspNetCore.Examples.ExamplesOperationFilter.SetRequestModelExamples(Operation operation, ISchemaRegistry schemaRegistry, ApiDescription apiDescription)
    at Swashbuckle.AspNetCore.Examples.ExamplesOperationFilter.Apply(Operation operation, OperationFilterContext context)
    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.CreatePathItems(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
    at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
    at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.d__6.MoveNext()
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()
    — End of stack trace from previous location where exception was thrown —
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()|url: http://localhost/swagger/v1-1/swagger.json|action:

    • Hi Mathew,

      Yes, Dependency Injection is supported, so what you have attempted to do should work.

      Have you registered IRelease with your service provider, i.e. services.AddSingleton();

      Failing that, does it work if you remove all the IRelease stuff, i.e. just return new { Version = 1 }.

      There’s a working example with Dependency Injection at the bottom of the ReadMe at https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters

      If you can’t get it to work then please raise an Issue over there on GitHub.

  16. Hi Matt,

    I appreciate your hasty reply. I just realized after posting this, I should have mentioned which version of Swashbuckle Example I was using. I was using the previous version (Swashbuckle.AspNetCore.Examples – 2.9.0). After searching my solution for upgrades to this package, I can across the Filters package:

    https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters

    Problem solved. I can use any interface registered within the startup file, or any concrete instance registered via the IOptions pattern.

    Thank you for you help, and your awesome work on this package.

  17. Hi Thanks for the example. Great help!

    I have a small question,
    my ExampleModel has a List property. Even though I have
    services.AddSwaggerGen (c =>
    {
    c.DescribeAllEnumsAsStrings();
    });

    it still displays numeric values for that property. How can I make it to display strings?

  18. Hi Sumera,

    In addition to what you have already configured for Swagger, I believe you also need to add a serialization setting to MVC. For example:

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddMvc(setupAction =>
    {
    // removed my references to ‘setupAction’

    })
    .AddJsonOptions(options =>
    {
    options.SerializerSettings.Formatting = Formatting.Indented;
    // convert enum to string
    options.SerializerSettings.Converters.Add(new StringEnumConverter());
    });
    }

  19. Hi Matt,

    Thanks for the great article. However I am facing one issue at the moment, not too sure what is causing it.

    If I omit Swashbuckle.AspNetCore.Examples from my code swagger runs fine. However once the package is present, it fails at run time with the error below. The installed packages are as follows

    System.Reflection.ReflectionTypeLoadException
    HResult=0x80131602
    Message=Unable to load one or more of the requested types.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.AddHeaderOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.AppendAuthorizeToSummaryOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.AuthorizationInputOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.DescriptionOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.ExamplesOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.AddFileParamTypesOperationFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Method ‘Apply’ in type ‘Swashbuckle.AspNetCore.Examples.AddResponseHeadersFilter’ from assembly ‘Swashbuckle.AspNetCore.Examples, Version=2.9.0.0, Culture=neutral, PublicKeyToken=aa1e9c5053bfbe95’ does not have an implementation.
    Source=System.Private.CoreLib
    StackTrace:
    at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
    at System.Reflection.RuntimeAssembly.get_DefinedTypes()
    at Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPart.get_Types()
    at Microsoft.AspNetCore.Mvc.Controllers.ControllerFeatureProvider.PopulateFeature(IEnumerable`1 parts, ControllerFeature feature)
    at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateFeature[TFeature](TFeature feature)
    at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetControllerTypes()
    at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.GetDescriptors()
    at Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorProvider.OnProvidersExecuting(ActionDescriptorProviderContext context)
    at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.UpdateCollection()
    at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.Initialize()
    at Microsoft.AspNetCore.Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider.GetChangeToken()
    at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.c__DisplayClass11_0.b__0()
    at Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration`1..ctor(Func`1 changeTokenProducer, Action`1 changeTokenConsumer, TState state)
    at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)
    at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointDataSourceBase.Subscribe()
    at Microsoft.AspNetCore.Mvc.Routing.ControllerActionEndpointDataSource..ctor(IActionDescriptorCollectionProvider actions, ActionEndpointFactory endpointFactory)
    at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
    at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.c__DisplayClass1_0.b__0(ServiceProviderEngineScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
    at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
    at Microsoft.AspNetCore.Builder.ControllerEndpointRouteBuilderExtensions.MapControllers(IEndpointRouteBuilder endpoints)
    at Geodesy.Api.Startup.c.b__5_1(IEndpointRouteBuilder endpoints) in D:\Development\geodesy\geodesy_api\Source\Geodesy.Api\Geodesy.Api\Startup.cs:line 160
    at Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseEndpoints(IApplicationBuilder builder, Action`1 configure)
    at Geodesy.Api.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in D:\Development\geodesy\geodesy_api\Source\Geodesy.Api\Geodesy.Api\Startup.cs:line 158
    at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
    at Microsoft.AspNetCore.Hosting.ConfigureBuilder.c__DisplayClass4_0.b__0(IApplicationBuilder builder)
    at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.c__DisplayClass13_0.b__2(IApplicationBuilder app)
    at Microsoft.Extensions.DependencyInjection.AutoRegisterMiddleware.c__DisplayClass4_0.b__0(IApplicationBuilder app)
    at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.c__DisplayClass0_0.g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
    at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.c__DisplayClass2_0.b__0(IApplicationBuilder app)
    at Microsoft.AspNetCore.HostFilteringStartupFilter.c__DisplayClass0_0.b__0(IApplicationBuilder app)
    at Microsoft.AspNetCore.Hosting.GenericWebHostService.d__31.MoveNext()

    • Hi Barry

      You’re using an old version of my package. It got renamed Swashbuckle.AspNetCore.Filters, so maybe you should try that version.

      Also see its GitHub page for updated instructions on how to use it. I recommend the “automatic annotation” approach.

      Matt

      • Hi Matt,

        Thanks for the help, using the recommend automatic approach it works perfect. However I did notice when the controller methods are formally annotated using the [SwaggerRequestExample(…)] attribute, then it throws at startup with the following error. Just curious if you know why that would happen.

        System.NullReferenceException: Object reference not set to an instance of an object.
        at Swashbuckle.AspNetCore.Filters.ExamplesOperationFilter.SetRequestModelExamples(OpenApiOperation operation, OperationFilterContext context)
        at Swashbuckle.AspNetCore.Filters.ExamplesOperationFilter.Apply(OpenApiOperation operation, OperationFilterContext context)

        Regards,
        Barry.

      • Hi Barry, not sure why that NullReferenceException is being thrown. If you’d like me to get to the bottom of it, please raise a GitHub issue for it.

      • Hi Matt.
        I have last version of Swashbuckle.AspNetCore.Examples(2.9.0) and
        Swashbuckle.AspNetCore.Filters(6.0.0) from nugets.
        But I have absolutely the same exception(Method ‘Apply’ in type … does not have an implementation)

  20. Hi,

    I have my post method taking a request parameter of type Jtoken, and due to this, the swagger documentation does not get created for it. Any thoughts?

  21. Excellent post!

    I followed the post step by step, but it doesn’t works when data comes from form.
    How could I generate swagger example request if my model comes from form?

    for example a controller action:
    public async Task Post([FromForm] PersonDTO creationDTO){
    //code…
    }

  22. Hello i follow your step on .net core 5.0, but i couldn’t get this result.
    I try it with https://www.nuget.org/packages/Swashbuckle.Examples/ and https://www.nuget.org/packages/Swashbuckle.AspNetCore.Filters/ but no one get your result.

    And when i try to add “c.OperationFilter()” i get this error in startup

    “The type ‘Swashbuckle.Examples.ExamplesOperationFilter’ must be convertible to ‘Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter’ in order to use it as parameter ‘TFilter’ in the generic method ‘void Microsoft.Extensions.DependencyInjection.SwaggerGenOptionsExtensions.OperationFilter(this SwaggerGenOptions, params object[])’”

    Can you help me, how can i get this result.

    Thank you.

Leave a comment