Julien Martin
Julien Martin

Reputation: 423

Array types with <example> tag not working with Swagger (swashbuckle.aspnetcore)

I am using the summary and example tags for the swagger documentation. I have a problem with the tag, it's not recognized by swagger when I use array :

I use swashbuckle.aspnetcore package Nuget.

Example :

[DataContract]
    public class HeaderResponse
    {
        /// <summary>
        /// Statut code
        /// </summary>
        ///<example>400</example>
        [DataMember]
        public int StatusCode { get; set; }
        /// <summary>
        /// Title
        /// </summary>
        /// <example>Erreur sur methode1</example>
        [DataMember]
        public string Title { get; set; }
        /// <summary>
        /// List of errors 
        /// </summary>
        ///<example>["entry1", "entry2", "entry3"]</example>
        [DataMember]
        public List<string> ErrorList { get; } = new List<string>();
}

On swagger documentation, array is not interpreted :

enter image description here

I found others solutions by using ISchemaFilter like this :

public class SwaggerExcludeFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            switch (context.Type.Name)
            {
                case "HeaderResponse":
                    foreach (var property in schema.Properties)
                    {
                        if (property.Value.Type == "array")
                        {
                            var array = new OpenApiArray();
                            array.Add(new OpenApiString("item1"));
                            array.Add(new OpenApiString("item2"));
                            array.Add(new OpenApiString("item3"));

                            property.Value.Example = array;
                        }
                    }
                    break;
            }
        }
    }

Is there no other way than to use ISchemaFilter to handle tags of type array?

Upvotes: 3

Views: 3878

Answers (4)

Chris Morgan
Chris Morgan

Reputation: 1104

Support for examples using XML comments on arrays was added in Swashbuckle.AspNetCore version 6.0.0.

It's mentioned in this GitHub issue and their documentation shows the following example:

/// <summary>
/// The sizes the product is available in
/// </summary>
/// <example>["Small", "Medium", "Large"]</example>
public List<string> Sizes { get; set; }

Upvotes: 2

Bohdan
Bohdan

Reputation: 2027

The quotes must be escaped using &quot;

/// <summary>
/// List of errors 
/// </summary>
///<example>[&quot;entry1&quot;,&quot;entry2&quot;,&quot;entry3&quot;]</example>
[DataMember]
public List<string> ErrorList { get; } = new List<string>();

Upvotes: 3

Yiyi You
Yiyi You

Reputation: 18139

You can try to do like this:

public List<string> ErrorList { get; } = new List<string>{"entry1", "entry2", "entry3"};

or:

[DataContract]
public class HeaderResponse
{
    public HeaderResponse()
    {
        ErrorList = new List<string> {"entry1", "entry2", "entry3" };
    }
    /// <summary>
    /// Statut code
    /// </summary>
    ///<example>400</example>
    [DataMember]
    public int StatusCode { get; set; }
    /// <summary>
    /// Title
    /// </summary>
    /// <example>Erreur sur methode1</example>
    [DataMember]
    public string Title { get; set; }
    /// <summary>
    /// List of errors 
    /// </summary>
    [DataMember]
    public List<string> ErrorList { get; set; }
}

Here is a demo:

[HttpPost("TestPar")]
        public IActionResult TestPar(HeaderResponse h)
        {
            return Json(h);
        }

result: enter image description here

Upvotes: 1

Wil Work
Wil Work

Reputation: 1

I have the same problem and I try this. you can add a condition on the name of the property and add the null return in order not to lose the example on the other properties. But the best solution would be to be able to find a generic solution. How is it possible to get the example tag and the property name with ISchemaFilter ? This is my solution :

public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
    schema.Example = GetExampleOrNullFor(schema, context);
}

private IOpenApiAny GetExampleOrNullFor(OpenApiSchema schema, SchemaFilterContext context)
{

switch (context.Type.Name)
{
    case "MyClass":
        foreach (var property in schema.Properties)
        {
            //Array property, which wraps its elements
            if (property.Value.Type == "array")
            {
                if (property.Key == "MyProperty1")
                {
                    var array = new OpenApiArray();
                    array.Add(new OpenApiString("item1"));
                    array.Add(new OpenApiString("item2"));
                    property.Value.Example = array;
                }
                else if (property.Key == "MyProperty2")
                {
                    var array = new OpenApiArray();
                    array.Add(new OpenApiString("item1"));
                    property.Value.Example = array;
                }
            }
        }
        return null;
    default:
        return null;
}

}

Upvotes: 0

Related Questions