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

Regression when updating from v5 to v6 regarding nullable types #2503

Closed
liesahead opened this issue Sep 23, 2022 · 7 comments
Closed

Regression when updating from v5 to v6 regarding nullable types #2503

liesahead opened this issue Sep 23, 2022 · 7 comments
Labels
responded Responded with solution or request for more info

Comments

@liesahead
Copy link

liesahead commented Sep 23, 2022

Upgrading from v5.6.3 to v6.2.3 (or v6.4.0, no difference) and generated schema is different now.

In v5.6.3 it was

"/api/Authentication/GetSomeData": {
    "get": {
      "tags": [
        "Authentication"
      ],
      "parameters": [
        {
          "name": "userId",
          "in": "query",
          "schema": {
            "type": "string",
            "nullable": true
          }
        },
        {
          "name": "token",
          "in": "query",
          "schema": {
            "type": "string",
            "nullable": true
          }
        }
      ],
    ...
    }
}

But now it's like this

"/api/Authentication/GetSomeData": {
    "get": {
      "tags": [
        "Authentication"
      ],
      "parameters": [
        {
          "name": "userId",
          "in": "query",
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "token",
          "in": "query",
          "schema": {
            "type": "string"
          }
        }
      ],
    ...
    }
}

Question is, how to make all nullable properties to have that "nullable": true in the schema again?

Tried to use options.SupportNonNullableReferenceTypes, but it has no effect.

@domaindrivendev
Copy link
Owner

This is by design in order to comply strictly with the OpenAPI spec because nullable doesn't make sense for query parameters. The relevant detail is here in the section entitled "Empty-Valued and Nullable Parameters":

Note: nullable is not the same as an optional parameter or an empty-valued parameter. nullable means the parameter value can be null. Specific implementations may choose to map an absent or empty-valued parameter to null, but strictly speaking these are not the same thing.

So, when you're API description says a query parameter is nullable, it's stating that it can be sent with the value null as follows:

GET /api/Authentication/GetSomeData?userId=null

And, this is not the same as saying it can be omittied (required: false) or empty-valued (allowEmptyValue: true) as follows:

GET /api/Authentication/GetSomeData?
GET /api/Authentication/GetSomeData?userId=

Furthermore, if userId=null is sent, then ASP.NET Core will initialize the corresponding parameter to the string value "null" as opposed to null. So, it really makes no sense to describe query parameters as nullable: true.

@domaindrivendev domaindrivendev added the responded Responded with solution or request for more info label Nov 15, 2022
@domaindrivendev
Copy link
Owner

domaindrivendev commented Nov 15, 2022

So, it might be worth understanding why you need nullable: true to be set for these parameters. Are you really stating that they may be set to null in a request as follows???

GET /api/Authentication/GetSomeData?userId=null

@zhuhuanzi
Copy link

zhuhuanzi commented Nov 18, 2022

Because when we use nswg to generate typescript code,this seems to be a required parameter, there is too much difference between the two, which seems to be a bad upgrade, Although it is the specification of OpenAPI.

image

@zhuhuanzi
Copy link

@liesahead
You can solve the problem in the following ways: #2536

services.AddTransient<ISchemaGenerator, XXXSchemaGenerator>();

@liesahead
Copy link
Author

@zhuhuanzi , didn't find an example with custom schema in referenced issue.

@MichelZ
Copy link

MichelZ commented Mar 20, 2023

We have tried to work around this problem by using a parameter filter:

public class SwaggerNullableParameterFilter : IParameterFilter
    {
        public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
        {
            if (!parameter.Schema.Nullable &&
                (context.ApiParameterDescription.Type.IsNullable(out _) || !context.ApiParameterDescription.Type.IsValueType))
            {
                parameter.Schema.Nullable = true;
            }
        }
    }
 services.AddSwaggerGen(options =>
            {
                options.ParameterFilter<SwaggerNullableParameterFilter>();
                [....]
});

@martincostello
Copy link
Collaborator

To make issue tracking a bit less overwhelming for the new maintainers (see #2778), I've created a new tracking issue to roll-up various nullability issues here: #2793.

We'll refer back to this issue from there and include it as part of resolving that issue, but I'm going to close this one to help prune the backlog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
responded Responded with solution or request for more info
Projects
None yet
Development

No branches or pull requests

5 participants