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

Net8.0: DTO Class Settings nullable not applied for FileParameter arguments #5110

Open
FerdinandStapenhorst opened this issue Feb 17, 2025 · 1 comment

Comments

@FerdinandStapenhorst
Copy link

FerdinandStapenhorst commented Feb 17, 2025

Version: 14.2.0.0

Even though I enabled the options

  • "Generate Nullable Reference Type (NRT) annotations"
    and
  • "Generate optional schema properties as nullable properties"

the argument FileParameter is not flagged as nullable.

I have the following Open API example spec:

info:
  title: Test
  version: 1.0.0
openapi: 3.0.3
paths:
  /api/item/{id}:
    patch:
      parameters:
        - $ref: '#/components/parameters/Id'
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateRequest'
        "required": false

      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Item'
          description: updated successfully.

components:
  parameters:
    Id:
      in: path
      name: id
      required: true
      schema:
        type: string
  schemas:
    Item:
      type: object
      properties:
        id:
          type: string  
    UpdateRequest:
      type: object
      properties:
        cover_image:
          format: binary
          type: string
          nullable: true        
        name:
          type: string
          nullable: true
      required: []

The functions signature created looks like this:

public virtual async System.Threading.Tasks.Task<Item> ItemAsync(string id, FileParameter cover_image = null, string? name = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))

Expected behavior

The functions should have the nullable marker (the question mark) at the FileParameter argument:

public virtual async System.Threading.Tasks.Task<Item> ItemAsync(string id, FileParameter? cover_image, string? name, System.Threading.CancellationToken cancellationToken)

@FerdinandStapenhorst
Copy link
Author

The fix looks like this:
In NSwag.CodeGeneration.CSharp.Models.CSharpOperationModel

Just check if the parameter is nullable and add the nullable type annotation (being the question-mark):

       protected override string ResolveParameterType(OpenApiParameter parameter)
        {
            var schema = parameter.ActualSchema;
            var isNullableTypeAnnotation = (!parameter.IsRequired || parameter.IsNullable(_settings.CodeGeneratorSettings.SchemaType)) ?
                "?" : "";

            if (parameter.IsBinaryBodyParameter)
            {
                if (_settings is CSharpControllerGeneratorSettings controllerSettings)
                {
                    if (schema.Type == JsonObjectType.Array && schema.Item.IsBinary)
                    {
                        return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
                            $"System.Collections.Generic.ICollection<Microsoft.AspNetCore.Http.IFormFile{isNullableTypeAnnotation}> " :
                            $"System.Collections.Generic.ICollection<System.Web.HttpPostedFileBase{isNullableTypeAnnotation}>";
                    }
                    else
                    {
                        return controllerSettings.ControllerTarget == CSharpControllerTarget.AspNetCore ?
                            $"Microsoft.AspNetCore.Http.IFormFile{isNullableTypeAnnotation}" :
                            $"System.Web.HttpPostedFileBase{isNullableTypeAnnotation}";
                    }
                }
                else
                {
                    return parameter.HasBinaryBodyWithMultipleMimeTypes ? $"FileParameter{isNullableTypeAnnotation}" : $"System.IO.Stream{isNullableTypeAnnotation}";
                }
            }

            if (schema.Type == JsonObjectType.Array && (schema.Item?.IsBinary ?? false))
            {
                return $"System.Collections.Generic.IEnumerable<FileParameter{isNullableTypeAnnotation}>";
            }

            if (schema.IsBinary)
            {
                if (parameter.CollectionFormat == OpenApiParameterCollectionFormat.Multi && !schema.Type.HasFlag(JsonObjectType.Array))
                {
                    return $"System.Collections.Generic.IEnumerable<FileParameter{isNullableTypeAnnotation}>";
                }

                return $"FileParameter{isNullableTypeAnnotation}";
            }

            return base.ResolveParameterType(parameter)
                .Replace(_settings.CSharpGeneratorSettings.ArrayType + "<", _settings.ParameterArrayType + "<")
                .Replace(_settings.CSharpGeneratorSettings.DictionaryType + "<", _settings.ParameterDictionaryType + "<");
        }

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