Swagger or OpenApi 3.0 examples in Swashbuckle.AspNetCore

If you’d like to generate request and response examples for your APIs, you no longer need to use my Swashbuckle.AspNetCore.Filters package.

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

For installation instructions, see the instructions in Swashbuckle.AspNetCore’s readme.

Request examples – POST

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpPost]
    public void Submit(WeatherForecast forecast)
    {
        // blah
    }
}

public class WeatherForecast
{
    /// <summary>
    /// The date of the forecast in ISO-whatever format
    /// </summary>
    public DateTime Date { get; set; }

    /// <summary>
    /// Temperature in celcius
    /// </summary>
    /// <example>25</example>
    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    /// <summary>
    /// A textual summary
    /// </summary>
    /// <example>Cloudy with a chance of rain</example>
    public string Summary { get; set; }
}

Results in:

Request examples – GET

OpenApi 3.0 supports examples on querystring parameters, which is pretty handy. Just add example= to the param:

/// <summary>
/// Retrieves a specific product by unique id
/// </summary>
/// <param name="id" example="123">The product id</param>
[HttpGet("{id}")]
public Product GetById(int id)

Courtesy of my pull request :-)

Or if you’ve got a reference type in your request (who would do that?), it still works:

// e.g. https://localhost:5001/weatherforecast/AU/MEL/1/2/2020
[HttpGet]
[Route("{country}/{city}/{day}/{month}/{year}")]
public string Get([FromRoute]WeatherRequest wr)
{
    // blah
}

public class WeatherRequest {
    /// <summary>
    /// The 2 digit country code
    /// </summary>
    /// <example>New Zealand, bro</example>
    public string Country { get; set;}
    public string City { get; set; }
    public int Day { get; set; }
    public int Month { get; set; }
    public int Year { get; set; }
}

Response examples

Response examples, again just add XML comments to your response class, and [ProducesResponseType]

[HttpGet]
[ProducesResponseType(typeof(WeatherForecast), StatusCodes.Status200OK)]
public WeatherForecast Get()
{
    // blah
}

// see WeatherForecast at the top of this post

Again, for installation instructions, see the instructions in Swashbuckle.AspNetCore’s readme.

22 thoughts on “Swagger or OpenApi 3.0 examples in Swashbuckle.AspNetCore

  1. So this addition makes it possible to use XML to add one example to a request/response class, right? I have an API where I have many endpoints using the same class, but where I need different examples. Can this way of using XML comments be used to specify the different example values of the request class for the individual endpoint? (From what I read from the Swashbuckle.Examples github, multiple examples for a single request class used to be impossible)

    • If your API accepts the same request for different endpoints, and you want to have different examples for each endpoint, then you’ll need to use my Swashbuckle.AspNetCore.Filters package.

      • (Seems my reply wasn’t submitted successfully, so I will repeat it, apologies if I just can’t see it yet)

        Thanks for your feedback! The project is running is not core, but standard .net framework 4.6 I think. Is there any way I can use those filters anyway?

      • You’re correct with your earlier comment – Swashbuckle.Examples only supports one example for each type on the request. It does support different examples for the same type on the response.

      • Indeed, thanks for the confirmation! I’d like to use your Swashbuckle.AspNetCore.Filters package instead, but I suppose this implies that my project also has to run asp.net core? My project is running framework 4.6, so I’m not sure if they are compatible. I realized this when your installation/use readme referred to files that didn’t exist in my project. Is there a way around this?

      • We’re getting off topic from this blog post, but yes, you’d need to upgrade to ASP.NET Core, which probably isn’t worth it. If however you’re starting a new project, then you should be using .NET Core instead of .NET Framework.

  2. I try to force a ‘date’ format like in your example above
    /// {summary}
    /// The date of the forecast in full-date format
    /// {/summary}
    /// {example}2020-05-31{/example}
    [DataType(DataType.Date)]
    public DateTime Date { get; set; }

    but the example does not appear to use the expected full-date format:
    {
    “name”: “date”,
    “in”: “query”,
    “description”: “The date of the forecast in full-date format”,
    “schema”: {
    “type”: “string”,
    “description”: “The date of the forecast in full-date format”,
    “format”: “date”,
    “nullable”: true,
    “example”: “31/05/2020 12:00:00 AM”
    }
    }

    Is there any way to have the example show in default swagger date format or same way as specified in the example xdoc?

  3. Hey Matt! I am currently having a slight problem with swashbuckle and maybe you could help me. Is there any way I can remove a field only from the example Json and keep it in the schema? Also, appreciate your work a lot man!

  4. Hi Matt, how can we make it work for multiple projects?

    I have a main project (MyApp) and a common lob (MyApp.Common). When using Swashbuckle 4.x I used the IExamplesProvider interface. But with 5.x it is not possible. However, when building the documentation (MyApp.xml), they won’t be any info about MyApp.Common. And as far as I know, it’s not possible to fuse easily the two XMLs. How can I still furnish example information from models in MyApp.Common using Swashbuckle 5.x?

    • Hi Cyril,

      You can add multiple XML files easily. Here’s a foreach I add to most of my projects

      var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, “MyApp*.xml”);
      foreach (var xmlFile in xmlFiles)
      {
      c.IncludeXmlComments(xmlFile);
      }

  5. Is there any way to specify examples for readonly fields? I am using proto3 which generates all array fields in the C# class as readonly and there does not seem to be a way to override that. I would like our end users to be able to see an example value in “Try it out” for these fields in the swagger doc however readonly fields never show up there.

      • Sure, here is the proto file:

        message DataRequest {
        repeated string ids = 1;
        google.protobuf.StringValue someField = 2;
        google.protobuf.StringValue someOtherField = 3;
        }

        This generates the a C# class with the following fields:

        public sealed partial class DataRequest : pb::IMessage {

        private readonly pbc::RepeatedField ids_ = new pbc::RepeatedField();
        public pbc::RepeatedField Ids { … }

        private string someField_;
        public string SomeField { … }

        private string someOtherField_;
        public string SomeOtherField { … }
        }

        So when Swashbuckle generates the swaggerdoc in the example above, you will see someField and someOtherField in the “Example value” but you won’t see the ids field. The ids field will only show up if you click on the “Schema” tab. This is a little misleading to end users since they can technically submit a value for ids when they use the “Try it out” feature but they wouldn’t be able to tell that is an option from the displayed “Example value”.

      • I guess it’s because pbc::RepeatedField is not a value type (int, string, etc). You should be able to create an example for that using my Swashbuckle.AspNetCore.Filters NuGet package.

  6. We have a controller action with [FromBody]List organizationIds, and Swachbuckle generates a default value (a list with a single guid) which we would like to change. However, adding a param tag with an example attribute doesn’t do the trick and since List is a built in type we can’t add the example there. Do you think we can use a custom type in which we can add the example we want (perhaps by extending List) or can you think of any other way?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s