Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Class Attribute for code generation causing 'Generic types are not valid.' during schema creation #5002

Open
ploring04 opened this issue Oct 18, 2024 · 0 comments

Comments

@ploring04
Copy link

ploring04 commented Oct 18, 2024

Our project has some simple class based generic attribute that will inject the boiler plate code for adding a property to a class.

[Property<LookupList>("LookupList")]

public partial class LookupListInfo
{
}

That will generate a class with this code generated inside the class

#region LookupList

LookupList _lookupList;

/// <summary>
/// 
/// </summary>
/// <name>Lookup List</name>
[Bindable(true)]
public LookupList LookupList() => _lookupList;
public LookupListInfo LookupList(kahua.kdk.hub.view.LookupList lookupList)
{
    _lookupList = lookupList;
    Properties.Properties(nameof(LookupList), lookupList?.Properties);
    OnLookupListChanged(lookupList);
    return this;
}

partial void OnLookupListChanged(LookupList lookupList);

#endregion LookupList

When this class is used as a return type in an endpoint the schema generator throws a 'Generic types are not valid.' exception during the call to ProcessResponseTypeAttributes.

[HttpGet]
public LookupListInfo GetInfo(string key)
{
    ...
}

Full stack trace

NJsonSchema.dll!NJsonSchema.Generation.JsonSchemaGenerator.ApplySchemaProcessors(NJsonSchema.JsonSchema schema, Namotion.Reflection.ContextualType contextualType, NJsonSchema.Generation.JsonSchemaResolver schemaResolver) Line 793	C#
NJsonSchema.dll!NJsonSchema.Generation.JsonSchemaGenerator.Generate<NJsonSchema.JsonSchema>(NJsonSchema.JsonSchema schema, Namotion.Reflection.ContextualType contextualType, NJsonSchema.Generation.JsonSchemaResolver schemaResolver) Line 155	C#
NJsonSchema.dll!NJsonSchema.Generation.JsonSchemaGenerator.Generate<NJsonSchema.JsonSchema>(Namotion.Reflection.ContextualType contextualType, NJsonSchema.Generation.JsonSchemaResolver schemaResolver) Line 121	C#
NJsonSchema.dll!NJsonSchema.Generation.JsonSchemaGenerator.GenerateWithReferenceAndNullability<NJsonSchema.JsonSchema>(Namotion.Reflection.ContextualType contextualType, bool isNullable, NJsonSchema.Generation.JsonSchemaResolver schemaResolver, System.Action<NJsonSchema.JsonSchema, NJsonSchema.JsonSchema> transformation) Line 291	C#
NSwag.Generation.dll!NSwag.Generation.OpenApiSchemaGenerator.GenerateWithReferenceAndNullability<NJsonSchema.JsonSchema>(Namotion.Reflection.ContextualType contextualType, bool isNullable, NJsonSchema.Generation.JsonSchemaResolver schemaResolver, System.Action<NJsonSchema.JsonSchema, NJsonSchema.JsonSchema> transformation) Line 81	C#
NSwag.Generation.dll!NSwag.Generation.Processors.OperationResponseProcessorBase.LoadDefaultSuccessResponse(System.Reflection.ParameterInfo returnParameter, string successXmlDescription, NSwag.Generation.Processors.Contexts.OperationProcessorContext context) Line 288	C#
NSwag.Generation.dll!NSwag.Generation.Processors.OperationResponseProcessorBase.ProcessOperationDescriptions(System.Collections.Generic.IEnumerable<NSwag.Generation.Processors.OperationResponseDescription> operationDescriptions, System.Reflection.ParameterInfo returnParameter, NSwag.Generation.Processors.Contexts.OperationProcessorContext context, string successResponseDescription) Line 232	C#
NSwag.Generation.dll!NSwag.Generation.Processors.OperationResponseProcessorBase.ProcessResponseTypeAttributes(NSwag.Generation.Processors.Contexts.OperationProcessorContext operationProcessorContext, System.Collections.Generic.IEnumerable<System.Attribute> responseTypeAttributes) Line 52	C#
NSwag.Generation.WebApi.dll!NSwag.Generation.WebApi.Processors.OperationResponseProcessor.Process(NSwag.Generation.Processors.Contexts.OperationProcessorContext context) Line 49	C#
NSwag.Generation.WebApi.dll!NSwag.Generation.WebApi.WebApiOpenApiDocumentGenerator.RunOperationProcessors(NSwag.OpenApiDocument document, System.Type controllerType, System.Reflection.MethodInfo methodInfo, NSwag.OpenApiOperationDescription operationDescription, System.Collections.Generic.List<NSwag.OpenApiOperationDescription> allOperations, NSwag.Generation.OpenApiDocumentGenerator generator, NSwag.OpenApiSchemaResolver schemaResolver) Line 251	C#
NSwag.Generation.WebApi.dll!NSwag.Generation.WebApi.WebApiOpenApiDocumentGenerator.AddOperationDescriptionsToDocument(NSwag.OpenApiDocument document, System.Type controllerType, System.Collections.Generic.List<System.Tuple<NSwag.OpenApiOperationDescription, System.Reflection.MethodInfo>> operations, NSwag.Generation.OpenApiDocumentGenerator swaggerGenerator, NSwag.OpenApiSchemaResolver schemaResolver) Line 218	C#
NSwag.Generation.WebApi.dll!NSwag.Generation.WebApi.WebApiOpenApiDocumentGenerator.GenerateForController(NSwag.OpenApiDocument document, System.Type controllerType, NSwag.Generation.OpenApiDocumentGenerator swaggerGenerator, NSwag.OpenApiSchemaResolver schemaResolver) Line 206	C#
NSwag.Generation.WebApi.dll!NSwag.Generation.WebApi.WebApiOpenApiDocumentGenerator.GenerateForControllersAsync(System.Collections.Generic.IEnumerable<System.Type> controllerTypes) Line 88	C#
NSwag.AspNet.Owin.dll!NSwag.AspNet.Owin.Middlewares.OpenApiDocumentMiddleware.GenerateDocumentAsync(Microsoft.Owin.IOwinContext context) Line 98	C#

The actual line of the exception is thrown here which goes deep into System.Reflection

private void ApplySchemaProcessors(JsonSchema schema, ContextualType contextualType, JsonSchemaResolver schemaResolver)
{
    ...
    var operationProcessorAttributes = contextualType
        .GetAttributes(true)
        .GetAssignableToTypeName(nameof(JsonSchemaProcessorAttribute), TypeNameStyle.Name);
    ...
}

I was trying to setup a TypeMapper which was not working so I dug into the code and realized even with a custom SchemaProcessor processor this line of code would still be called and throw the exception and there was no TypeMapper check.

I am still relatively new to NSwag so I was not sure the best way to resolve this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant