Search code examples
c#swaggerasp.net-core-webapiwebapi.net-8.0

Web Api over ride Swagger Example Value


I have written a c# Web Api using .net 8 with a post method that looks like the following:

[Route("/v1.0/Test/TestXmlCall")]
[Consumes("application/xml")]
[HttpPost]    
public async Task<IResult> TestXmlCall([FromBody][SwaggerTryItOutDefaultValue("<Test></Test>")] XDocument xml)
{
    var requestType = APIRequestType.ReportTable2;
    var acerTableType = AcerTableType.Table2;

    return await ReportNonStandardTrade(requestType, acerTableType);
}

This works as expected but in swagger the exmple value shows the full description of the XDocument value

enter image description here

I have tried over riding thus using the SwaggerTryItOutDefaultValue (and apply to the Xdocumnet parameter) where the code looks like the below:

public class SwaggerTryItOutDefaultValue : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.ParameterInfo != null)
        {
            var att = context.ParameterInfo.GetCustomAttribute<SwaggerTryItOutDefaultValueAttribute>();
            if (att != null)
            {
                schema.Example = new Microsoft.OpenApi.Any.OpenApiString(att.Value.ToString());
            }
        }
    }
}

public class SwaggerTryItOutDefaultValueAttribute : Attribute
{
    public string Value { get; }

    public SwaggerTryItOutDefaultValueAttribute(string value)
    {
        Value = value;
    }
}

but this fails to change what is shown in the example value?

Is there a way to change the value shown in the ExampleValue?

Thanks for any help.

Nick


Solution

  • I found this library which might be of help to you. I have an endpoint like this:

    [Route("TestXmlCall")]
    [Consumes("application/xml")]
    [HttpPost]
    public async Task<string> TestXmlCall([FromBody] Word xml)
    {
        return "success";
    }
    
    public class Word
    {
        public string Words { get; set; }
        public string Phonetic { get; set; }
        public string Paraphrase { get; set; }
    }
    

    And by default, I will have test sample like this(XML is case sensitive so that using sample below will get 400 error, the node should be changed to Upper case like Words instead of words to match the model):

    <?xml version="1.0" encoding="UTF-8"?>
    <Word>
        <words>string</words>
        <phonetic>string</phonetic>
        <paraphrase>string</paraphrase>
    </Word>
    

    But if I add [SwaggerRequestExample(typeof(Word), typeof(WordExample))] attribute to my endpoint, and modify my Program.cs like this:

    builder.Services.AddControllers().AddXmlSerializerFormatters().AddXmlDataContractSerializerFormatters(); 
    builder.Services.AddEndpointsApiExplorer();
    //builder.Services.AddSwaggerGen();
    builder.Services.AddSwaggerGen(c =>
    {
        c.ExampleFilters();
    });
    builder.Services.AddSwaggerExamplesFromAssemblyOf<WordExample>();
    

    And have example class for this endpoint like this:

    public class WordExample : IExamplesProvider<Word>
    {
        public Word GetExamples()
        {
            return new Word
            {
                Words = "example word",
                Phonetic = "example phonetic",
                Paraphrase = "example paraphrase"
            };
        }
    }
    

    I will have default value for this endpoint. Here's my test result:

    enter image description here