question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrong Xml example data generation

See original GitHub issue

Hi all, i have a problem with auto-generated Xml example value on Swagger-UI, the xml structure is invalid and can’t be used to test api

Steps to reproduce the problem:

  • Create a new Web Api 2 project using VS2015. New -> Project -> Asp.Net Web Application -> WebApi
  • Add a class with collection like this
public class Foo
    {
        public string Name { get; set; }
        public int Code { get; set; }
        public IList<FooItem> Items { get; set; }
    }

    public class FooItem
    {
        public string ItemName { get; set; }
        public int ItemCode { get; set; }
    }
  • Modify the controller ValuesController.cs
        public void Post([FromBody]IList<Foo> list)
        {
        }
  • Now look the Xml sample data generated by standard api help page of asp.net web api projeject
<ArrayOfFoo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SwashbuckleXml.Models">
  <Foo>
    <Code>2</Code>
    <Items>
      <FooItem>
        <ItemCode>2</ItemCode>
        <ItemName>sample string 1</ItemName>
      </FooItem>
      <FooItem>
        <ItemCode>2</ItemCode>
        <ItemName>sample string 1</ItemName>
      </FooItem>
    </Items>
    <Name>sample string 1</Name>
  </Foo>
  <Foo>
    <Code>2</Code>
    <Items>
      <FooItem>
        <ItemCode>2</ItemCode>
        <ItemName>sample string 1</ItemName>
      </FooItem>
      <FooItem>
        <ItemCode>2</ItemCode>
        <ItemName>sample string 1</ItemName>
      </FooItem>
    </Items>
    <Name>sample string 1</Name>
  </Foo>
</ArrayOfFoo>

and the Xml sample data generated from Swagger UI

<?xml version="1.0"?>
<Foo>
  <Name>string</Name>
  <Code>1</Code>
  <Items>
    <ItemName>string</ItemName>
    <ItemCode>1</ItemCode>
  </Items>
</Foo>
  • As you can see the Xml generated from swagger don’t has Foo root collection and FooItem element
  • You can’t use the auto-generated xml sample data on swagger UI, the format is not valid

Any suggestions?

Thanks in advance, Diego

SwashbuckleXml.zip

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:22 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
euroform-pacommented, Oct 16, 2019

@joegithub @GeorgyOkov Finally I got it working with Xml. Following is the CustomXmlSchemaFilter that handles return of collection, collection property in POCO.

public class CustomXmlSchemaFilter : ISchemaFilter
    {
        private const string _SCHEMA_ARRAY_TYPE = "array";
        private const string _SCHEMA_STRING_TYPE = "string";
        private const string _PREFIX_ARRAY = "ArrayOf";

        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.ApiModel.Type.IsValueType)
                return;

            if (schema.Type == _SCHEMA_STRING_TYPE)
                return;

            schema.Xml = new OpenApiXml
            {
                Name = context.ApiModel.Type.Name
            };

            if (schema.Type == _SCHEMA_ARRAY_TYPE && schema.Items.Reference != null)
            {
                schema.Xml = new OpenApiXml
                {
                    Name = $"{_PREFIX_ARRAY}{schema.Items.Reference.Id}",
                    Wrapped = true,
                };
            }

            if (schema.Properties == null)
            {
                return;
            }

            foreach (var property in schema.Properties.Where(x => x.Value.Type == _SCHEMA_ARRAY_TYPE))
            {
                property.Value.Items.Xml = new OpenApiXml
                {
                    Name = property.Value.Items.Type,
                };
                property.Value.Xml = new OpenApiXml
                {
                    Name = property.Key,
                    Wrapped = true
                };
            }
        }
    }

Specify to use this Schema filter in Swagger via following:

services.AddSwaggerGen(c =>
{
    ...

    c.SchemaFilter<CustomXmlSchemaFilter>();
});

Hope this helps.

0reactions
cobrulcommented, Jun 23, 2021

The solution above doesn’t work for an return of type string[] or IEnumerable<string>, unless you add also name for items which are not reference:

public class CustomXmlSchemaFilter : ISchemaFilter
{
    private const string _SCHEMA_ARRAY_TYPE = "array";
    private const string _SCHEMA_STRING_TYPE = "string";
    private const string _PREFIX_ARRAY = "ArrayOf";

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsValueType)
            return;

        if (schema.Type == _SCHEMA_STRING_TYPE)
            return;

        schema.Xml = new OpenApiXml
        {
            Name = context.Type.Name
        };

        if (schema.Type == _SCHEMA_ARRAY_TYPE && schema.Items.Reference != null)
        {
            schema.Xml = new OpenApiXml
            {
                Name = $"{_PREFIX_ARRAY}{schema.Items.Reference.Id}",
                Wrapped = true,
            };
        }
        // add this for string[]
        if (schema.Type == _SCHEMA_ARRAY_TYPE && schema.Items.Type != null)
        {
            schema.Xml = new OpenApiXml
            {
                Name = $"{_PREFIX_ARRAY}{schema.Items.Type}",
                Wrapped = true,
            };
            schema.Items.Xml = new OpenApiXml
            {
                Name = schema.Items.Type
            };
        }

        if (schema.Properties == null)
        {
            return;
        }

        foreach (var property in schema.Properties.Where(x => x.Value.Type == _SCHEMA_ARRAY_TYPE))
        {
            property.Value.Items.Xml = new OpenApiXml
            {
                Name = property.Value.Items.Type,
            };
            property.Value.Xml = new OpenApiXml
            {
                Name = property.Key,
                Wrapped = true
            };
        }
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Wrong Xml example data generation · Issue #1050
Hi all, i have a problem with auto-generated Xml example value on Swagger-UI, the xml structure is invalid and can't be used to...
Read more >
Xml Sample Generator - Wrong output?
I am trying to generate a sample xml from a given xsd at runtime. For this purpose I am using the XML Sample...
Read more >
Invalid xml data generator
I want to generate problematic data (single space, invalid item, etc.). It could be done by mutation of valid xml, or by generating...
Read more >
XML generate exceptions
The following table shows the exception codes that can occur during XML generation. The exception codes are returned in special register XML-CODE ....
Read more >
XML Data Generation Failed Error (Doc ID 1907190.1)
Changing the Date Format on Template Causes Sending Process Failed: XML Data Generation Failed Error (Doc ID 1907190.1).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found