Within my Asp.Net Core v5 application we have the following models
public class StorageRecordTypeMetadataBase
{
public string PropertyName { get; set; }
public bool Required { get; set; }
}
public class StringRecordTypeMetadata: StorageRecordTypeMetadataBase
{
public string? ValidationRegex { get; set; }
}
public class NumericRecordTypeMetadata : StorageRecordTypeMetadataBase
{
public int MinValue { get; set; }
public int MaxValue { get; set; }
}
In my application Startup.cs
I have registered Swagger and NSwag setup as following:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSwaggerDocument();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseOpenApi();
app.UseSwaggerUi3();
}
}
In order to support polymorphism, I have followed the guideline as written by NSwag creator: Guide on inheritance in NSwag, and here is how my model looks like updated:
[JsonConverter(typeof(JsonInheritanceConverter), "discriminator")]
[KnownType(typeof(StringRecordTypeMetadata))]
[KnownType(typeof(NumericRecordTypeMetadata))]
public class StorageRecordTypeMetadataBase
{
public string PropertyName { get; set; }
public bool Required { get; set; }
}
As soon as I run the application, swagger fails as swagger.json could not be generated. Upon investigating the issue I can see the following error message once I try to manually navigate to /swagger/v1/swagger.json
System.MissingMethodException: Method not found: 'System.String Namotion.Reflection.XmlDocsExtensions.GetXmlDocsSummary(System.Reflection.MemberInfo)'. at NSwag.Generation.Processors.OperationSummaryAndDescriptionProcessor.ProcessSummary(OperationProcessorContext context, List
1 attributes) at NSwag.Generation.Processors.OperationSummaryAndDescriptionProcessor.Process(OperationProcessorContext context) at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.RunOperationProcessors(OpenApiDocument document, ApiDescription apiDescription, Type controllerType, MethodInfo methodInfo, OpenApiOperationDescription operationDescription, List
1 allOperations, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver) at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.AddOperationDescriptionsToDocument(OpenApiDocument document, Type controllerType, List1 operations, OpenApiDocumentGenerator swaggerGenerator, OpenApiSchemaResolver schemaResolver) at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.GenerateForControllers(OpenApiDocument document, IGrouping
2[] apiGroups, OpenApiSchemaResolver schemaResolver) at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.GenerateAsync(ApiDescriptionGroupCollection apiDescriptionGroups) at NSwag.Generation.AspNetCore.AspNetCoreOpenApiDocumentGenerator.GenerateAsync(Object serviceProvider) at NSwag.AspNetCore.OpenApiDocumentProvider.GenerateAsync(String documentName) at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.GenerateDocumentAsync(HttpContext context) at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.GetDocumentAsync(HttpContext context) at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.GetDocumentAsync(HttpContext context) at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I have tried to include the referenced package Namotion.Reflection even myself but that did not help either. Is there anything that I have missed during my configuration?
This was supposed to add discriminator
field within the base model so that it would be automatically recognized when I generate my models on front end (React) side. I can achieve this behavior by moving away from NSwag, to Swashbuckle like following:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSwaggerGen(c =>
{
c.UseAllOfForInheritance();
c.SelectSubTypesUsing(baseType =>
{
return typeof(StorageRecordType).Assembly.GetTypes().Where(type => type.IsSubclassOf(baseType));
});
c.SelectDiscriminatorNameUsing((baseType) => "itemType");
c.SelectDiscriminatorValueUsing((subType) => subType.Name);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger((SwaggerOptions c) => { });
app.UseSwaggerUI();
}
}
However this completely breaks the NSwag generation process on my React side. Methods from all controllers are put together into a single Client (instead of being separated per controller name), plus some of the classes required in the parameters seem to be gone as well.
How can I fix the NSwag in order to get the discriminator value in my swagger.json response?
Ok so the issue was, that I was using older version of Nswag.AspNetCore
. Instead of version 13.10.8
I upgraded to 13.15.5
, which works great with package NJsonSchema v 10.6.6