Reputation: 499062
I am converting a SOAP API to REST, in a legacy web application.
I started off with a webapi project (C#) - setting it up with swagger and swashbuckle. I've added end-points to this, annotated with XML comments. This is using full framework, not .NET Core.
The comments all appear as expected in the swagger-ui (XML document generation is working fine, file is picked up by swagger via config).
This project is referencing the old SOAP API classes (written in VB.NET). I have tried annotating these classes with RequiredAttribute
(for example) and adding XML comments to them, but these are not showing up at all in swagger-ui. They are setup in a very shallow class hierarchy (base class that they all inherit from - I am including this information for completeness).
These other VB.NET projects do have XML documentation enabled and I see the XML files with the documentation I've added in the webapi project bin directory, as expected. I have added these to the swagger configuration and I believe they are loaded correctly (as there are no exception when loading the page).
However - none of the models in swagger-ui show any of the DataAnnotation
attributes I've added or any of the XML documentation in these VB.NET projects.
I'd like to get them to show up as well as have them listed in the Modles section of swagger-ui (which is non-existent at this time).
What am I missing?
Update:
I've done some testing with an external library (C#, full framework), using a test model.
This had just worked as expected - XML documentation and DataAnnotation
attributes are discovered and display on swagger-ui without issue.
Am now suspecting VB.NET, though possibly this is an issue with the VB.NET projects being WCF projects.
Update:
Done the same with a new VB.NET class library and everything just worked™, so... possibly the class hierarchy or something with these other VB projects (probably not simple class libraries or something else is in the way).
Update:
It isn't the inheritance heirarchy.
Upvotes: 1
Views: 1422
Reputation: 1
A little late to the conversation, but hopefully this will help those stumbling across this question. The answer applies to .NET Framework +4.5 using Swagger(NSwag).
When using WebAPI 2. You will need to enable the UseXmlSerializer in the WebApiConfof.cs file:
ublic static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// ...
// Web API routes
//...
// You will need this to get the pipeline to produce XML attributes
// instead of XML elements
config.Formatters.XmlFormatter.UseXmlSerializer = true;
}
}
Then you will need to add a schema filter to your SwaggerConfig.cs file
// If you want to post-modify "complex" Schemas once they've been
// generated, the board or for a
// specific type, you can wire up one or more Schema filters.
//
c.SchemaFilter<XmlAttributeFilter>();
Then create your schema filter that iterates through all the schema elements to find all properties that have been annotated with the [XmlAttribute] attribute. In our case we also set the [JsonProperty] attribute:
public class XmlAttributeFilter : ISchemaFilter
{
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
if (schema == null || schema.properties == null || type == null)
return;
IEnumerable<PropertyInfo> xmlAttrProperties = type.GetProperties()
.Where(t => t.GetCustomAttribute<XmlAttributeAttribute>() != null);
foreach (var xmlAttrProperty in xmlAttrProperties)
{
var xmlAttribute = xmlAttrProperty.GetCustomAttribute<XmlAttributeAttribute>();
if (xmlAttribute != null && schema.properties.ContainsKey(xmlAttribute.AttributeName))
{
var foundSchema = schema.properties[xmlAttribute.AttributeName];
foundSchema.xml = new Xml { attribute = true };
}
}
}
}
This can all be done within the SwaggerConfig class.
Upvotes: 0
Reputation: 499062
Turns out the VB.NET classes are all marked with the good old SerializableAttribute
.
This causes the models to look completely different in swagger-ui and therefore none of the annotations (DataAnnotation
attributes and XML comments) to work correctly.
This is also causing all the properties to come up with an underscore in front of their names (which I was also curious about, and forgot to mention in my question).
To solve my actual problem, I found a solution on this GitHub issue.
Namely, ensuring the correct JSON formatter is to be used (in Global.asax.cs
):
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver();
Upvotes: 2