在 ASP.NET Core 3.0 Swagger 中将字符串标记为不可空

Mark strings as non-nullable in ASP.NET Core 3.0 Swagger

我使用的是 ASP.NET Core 3 和 Swashbuckle,大部分都是默认配置,我有一个 DTO 参数,上面有一个我希望不可为 null 的字符串。我怎样才能做到这一点?请注意,Required 和 nullability 是 Swagger 中的独立问题。

它也使用 C#8 和不可为空的东西,因此编译器应该已经将 属性 注释为不可为空。可以理解的是,Swashbuckle 尚未更新以考虑到这一点(也许不能),但我希望能够以某种方式覆盖生成的元数据。

class MyDto {
    [Required]
    // I want this to show as non-nullable in the swagger documentation (and ideally also be non-nullable in the binding)
    public string TestProp { get; set; }
}

[HttpPost]
public void Post([FromBody] MyDto requestModel) {
}

我试过将其设为必需。我还尝试添加 Newtonsoft 注释,但其中 none 似乎可以做到。

生成的 Swagger 文档的相关位:

    "MyDto": {
      "required": [
        "testProp"
      ],
      "type": "object",
      "properties": {
        "testProp": {
          "type": "string",
          "nullable": true
        }
      },
      "additionalProperties": false
     }

请注意,将字符串参数直接作为参数不会生成可空属性。例如

[HttpPost("testPost")]
public void Post([FromBody] [Required] string testProp) {
}

将生成

"/api/test/testPost": {
  "post": {
    "tags": [
      "Test"
    ],
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {
            "type": "string"
          }
        },
        "text/json": {
          "schema": {
            "type": "string"
          }
        },
        "application/*+json": {
          "schema": {
            "type": "string"
          }
        }
      },
      "required": true
    },
    "responses": {
      "200": {
        "description": "Success"
      }
    }
  }
},

直到 v4.01 nullable:true 为可选字符串发出。这在第一个 5.0 RC 版本中被打破并且 nullable:true 根本没有为可选字符串发出。显然,这是错误的。

Starting with 5.0 RC3 可选字符串再次可以为空。

要指定可选字符串 不可 为 null,您需要将 [JsonProperty(Required = Required.DisallowNull)] 添加到 属性。从 one of Swashbuckle's unit tests 复制,这个:

    [JsonProperty(Required = Required.DisallowNull)]
    public string StringWithRequiredDisallowNull { get; set; }

应该set the property's Nullable flag

Assert.False(schema.Properties["StringWithRequiredDisallowNull"].Nullable);

并发出 nullable:true.

您现在可以使用 nullable reference types 将字符串标记为可选或必需:

  • 为您的project/solution

    启用可为空的引用类型
  • 将 Dtos 中的字符串标记为可为空:

    public class ExampleDto
    {
       [StringLength(64, MinimumLength = 4)]
       public string RequiredString { get; set; }
    
       [StringLength(200)]
       public string? OptionalString { get; set; }
    }
    
  • 在您的 Startup.cs

    中启用 Swagger 支持
    services.AddSwaggerGen(options =>
    {
        options.SupportNonNullableReferenceTypes();
    });
    

这导致:

{
  "Example": {
    "type": "object",
    "properties": {
      "requiredString": {
        "maxLength": 64,
        "minLength": 4,
        "type": "string"
      },
      "optionalString": {
        "maxLength": 200,
        "minLength": 0,
        "type": "string",
        "nullable": true
      }
    },
    "additionalProperties": false
  }
}