Swashbuckle.aspnetcore: Casing of Propertynames (Xml issue)

Created on 30 Apr 2018  路  5Comments  路  Source: domaindrivendev/Swashbuckle.AspNetCore

We are using Swashbuckle for our API documentation. Our web interface should support XML.
We have done this with a request filter and adding XML serialization for MVC.

Now we have the issue, that the SwaggerContractResolver, which is used to generate the api.json, uses camel case as naming strategy. Now the sample data on the UI uses those camel case properties.
Xml is case sensitive, and so the XmlSerializer is. This leads to invalid models on the controller side. The JSON parser, on the other hand, ignores the casing.

I created a small sample project to show the problem in a lean way: Sample Repository.
Is there a way to get this working without attributing hundreds of properties on all models ([JsonProperty(PropertyName = "Xyz")]) or weaving them? A possible solution might be introducing an interface for the SwaggerContractResolver so that it can be replaced using IOC.

Most helpful comment

This does not seem to work on objects with embedded relations:

<?xml version="1.0" encoding="UTF-8"?>
<SomeClass>
    <contact>
        <Civility>string</Civility>
        <EmailAddress>string</EmailAddress>
    </contact>
  <SomeAttribute>string</SomeAttribute>
  <SomeOtherAttribute>string</SomeOtherAttribute>
</SomeClass>

"contact" is not in PascalCase, while literally all other attributes are. I used the debugger on the XmlSchemaFilter class, and while I can see "contact" in the loop, it seems that something else renames it again later.

All 5 comments

So, just to clarify ... it's not actually the SwaggerContractResolver that's causing the problem. It dictates the casing of the Swagger JSON itself and not the casing of API types that it's describing (a little meta but hopefully that makes sense).

Swagger is definitely optimized for describing JSON payloads, highlighted by the fact that the Schema object is heavily based on JSON Schema. However, it does provide some support for describing XML payloads through the Schema.xml field (described here).

So, to solve your problem you can write a simple Operation Filter (see readme) that leverages that field to describe the additional detail - i.e. that property names should be pascal cased when the media type is XML.

// Startup.cs
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Version = "V1", Title = "My API" });
    ...
    c.SchemaFilter<XmlSchemaFilter>();
});

// XmlSchemaFilter.cs
public class XmlSchemaFilter : ISchemaFilter
{
    public void Apply(Schema model, SchemaFilterContext context)
    {
        if (model.Properties == null) return;

        foreach (var entry in model.Properties)
        {
            var name = entry.Key;
            entry.Value.Xml = new Xml
            {
                Name = name.Substring(0, 1).ToUpper() + name.Substring(1)
            };
        }
    }
}

Give it a try and let me know if it works?

Thanks for your fast feedback. Your suggested solution works like a charm :thumbsup:
I totally missed that xml property in the schema filter. Thanks a lot!

This does not seem to work on objects with embedded relations:

<?xml version="1.0" encoding="UTF-8"?>
<SomeClass>
    <contact>
        <Civility>string</Civility>
        <EmailAddress>string</EmailAddress>
    </contact>
  <SomeAttribute>string</SomeAttribute>
  <SomeOtherAttribute>string</SomeOtherAttribute>
</SomeClass>

"contact" is not in PascalCase, while literally all other attributes are. I used the debugger on the XmlSchemaFilter class, and while I can see "contact" in the loop, it seems that something else renames it again later.

Could an OperationFilter help, and if so, how? I found this other issue: https://github.com/domaindrivendev/Swashbuckle/issues/714

I tried playing with the entry.Value.Xml mentioned above, adding a namespace for example, and the "contact" tag isn't changed as the other tags are. What other stuff is interesting onto entry.Value item, apart from entry.Value.Xml ?

@domaindrivendev I have the same issue as @scambier.
Do you have any clue why it can happen?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rgelb picture rgelb  路  3Comments

tibitoth picture tibitoth  路  3Comments

m-demydiuk picture m-demydiuk  路  3Comments

jderus picture jderus  路  4Comments

jluqueba picture jluqueba  路  4Comments