【问题标题】:How to implement OpenAPI readOnly and writeOnly with Swashbuckle如何使用 Swashbuckle 实现 OpenAPI 只读和只写
【发布时间】:2021-07-03 15:28:12
【问题描述】:

我在 .Net 5.0 Web API 中使用 Swashbuckle (6.1.1)。我仍在学习,但我想实现一个类,其中某些属性仅在使用GET“读取”时有效,而在使用POST“写入”时其他属性有效。根据OpenAPI spec

您可以使用 readOnly 和 writeOnly 关键字将特定属性标记为只读或只写。这很有用,例如,当 GET 返回的属性多于 POST 中使用的属性时——您可以在 GET 和 POST 中使用相同的模式并将额外的属性标记为只读。 readOnly 属性包含在响应中但不包含在请求中,并且 writeOnly 属性可以在请求中发送但不在响应中。

这正是我想要实现的。但是,我正在努力让 Swashbuckle 使用 readOnlywriteOnly 密钥生成 OpenAPI 规范。

例如:

    public class testDetails
    {            
        public string commonProperty { get; set; }           
        public  string readOnlyProperty { get; set; }
        public string writeOnlyProperty {  get; set; }
    }

    [ProducesResponseType(StatusCodes.Status200OK)]    
    [HttpGet("Get")]
    public IActionResult Get([FromQuery] testDetails details)
    {
        Debug.WriteLine($"commonProperty is {details.commonProperty}");
        Debug.WriteLine($"readOnlyProperty is {details.readOnlyProperty}");
        Debug.WriteLine($"writeOnlyProperty is {details.writeOnlyProperty}");
        return Ok();
    }

我希望在生成的swagger.json 中将readOnlyProperty 标记为readOnly,并将writeOnlyProperty 标记为writeOnly

实际上,writeOnlyProperty 不应该作为任何GET 的属性出现(但会出现在POST/PUT),相反,readOnlyProperty 应该可用于GET,但是不是POST

我尝试添加 System.ComponentModel [ReadOnly] 属性,但没有效果。我也尝试将访问器更改为

 public class testDetails
    {            
        public string commonProperty { get; set; }           
        public  string readOnlyProperty { get; internal set; }
        public string writeOnlyProperty {  internal get; set; }
    }

... 但这最终会完全隐藏属性。这些都不会影响代码的实际操作,但我仍然希望属性只能在需要的地方可写,否则只读 - 正如 OpenAPI 规范所描述的那样。有没有办法做到这一点,而无需创建单独的“读写类”?

【问题讨论】:

    标签: asp.net-web-api openapi swashbuckle


    【解决方案1】:

    您可以使用包Swashbuckle.AspNetCore.Annotations 中的SwaggerSchemaAttribute 注释只读和只写属性。这将允许您使用 readOnlywriteOnly 关键字生成 OpenAPI 规范,并隐藏 Swagger UI 中的属性。

    按照以下步骤操作:

    1. 将以下 Nuget 包安装到您的 ASP.NET Core 应用程序中。
    Install-Package Swashbuckle.AspNetCore.Annotations
    
    1. Startup.csConfigureServices 方法中,在Swagger 配置块中启用注释:
    services.AddSwaggerGen(c =>
    {
       ...
    
       c.EnableAnnotations();
    });
    
    1. 为模型添加属性:
    public class TestDetails
    {
        public string CommonProperty { get; set; }
    
        [SwaggerSchema(ReadOnly = true)]
        public string ReadOnlyProperty { get; set; }
    
        [SwaggerSchema(WriteOnly = true)]
        public string WriteOnlyProperty { get; set; }
    }
    

    您的控制器可能如下所示:

    [ApiController]
    [Route("[controller]")]
    public class DataController : ControllerBase
    {
        private TestDetails testDetails = new TestDetails()
        {
            CommonProperty = "Common prop value",
            ReadOnlyProperty = "ReadOnly prop value",
            WriteOnlyProperty = "WriteOnly prop value"
        };
    
        public DataController()
        {
            
        }
    
        [HttpGet]
        [ProducesResponseType(typeof(TestDetails), (int) HttpStatusCode.OK)]
        public IActionResult Get()
        {
            return Ok(testDetails);
        }
    
        [HttpPost]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        public IActionResult Post([FromBody] TestDetails details)
        {
            return Ok();
        }
    }
    

    【讨论】:

    • 需要注意的一点:如果您有一个属性标记为必需,这将阻止这个只读注释产生任何影响
    猜你喜欢
    • 2019-09-17
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2012-08-24
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多