我有一个小小的swaggergen UI输出,如下所示: [![put request] [1]] [1]
并且(出于某些原因),我不想使用典型的验证属性,而是在请求正文中进行验证。我的容器名称是一个Azure Blob存储容器,因此它必须是3-63个字符,并且与一个简单的正则表达式匹配(没有大写字母,基本上是字母数字)。
我想修改UI来显示这些要求...因此,我编写了OperationFilter和Attribute。我以为我想修改SwaggerParameters,在那儿我注意到了一个方便的模式,带有“ MinLength”,“ MaxLength”和“ Pattern”之类的参数,换句话说,正是我想在UI上显示的内容。所以我修改了。输出为:
"put": {
"tags": [
"Values"
],
"summary": "API Operation – Create & Update\r\n::\r\nCreates a new content file entry in the containername provided.",
"description": "If the container name has the word public in it, then the container\r\nshall be public otherwise the container, identified by the\r\ncontainername, shall be private. If the file, identified by the\r\nfilename parameter on the URI, already exists then the existing blob\r\nentry will be overwritten with the new fileData uploaded.",
"operationId": "Put",
"parameters": [
{
"name": "containername",
"in": "path",
"description": "The container the file resides in.",
"required": true,
"schema": {
"maxLength": 63,
"minLength": 3,
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
"type": "string"
}
},
{
"name": "fileName",
"in": "path",
"description": "The name of the file uploaded. This shall become the block blob Id.",
"required": true,
"schema": {
"maxLength": 75,
"minLength": 1,
"pattern": "\\S",
"type": "string"
}
}
],
问题是,UI外观相同。我应该修改些什么才能呈现这些值?
执行此操作的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using static Foo.SwaggerParameterDescriptions;
namespace Foo
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SwaggerPathParameterDescriptions : Attribute
{
public enum Description
{
Default,
MinLength,
MaxLength,
Pattern
}
public string ParameterName { get; set; }
public Dictionary<Description, dynamic> Settings { get; set; }
public SwaggerPathParameterDescriptions(string parameterName, string json)
{
Dictionary<string, dynamic> dict = JsonSerializer
.Deserialize<Dictionary<string, dynamic>>(json);
Dictionary<Description, dynamic> settings = dict.Entries()
.ToDictionary(entry => (Description)Enum.Parse(typeof(Description), (string)entry.Key),
entry => entry.Value);
ParameterName = parameterName;
Settings = settings;
}
public IEnumerable<SwaggerParameterSchemaDescription> GetSwaggerParameters()
{
return Settings.Keys.Select(key =>
new SwaggerParameterSchemaDescription { ParameterName = key, Value = Settings[key] });
}
}
public class SwaggerParameterSchemaDescription
{
public Description ParameterName { get; set; }
public dynamic Value { get; set; }
public void ApplyTo(OpenApiParameter param)
{
string representation = $"{Value}";
switch (ParameterName)
{
case Description.Default:
param.Schema.Default = new OpenApiString(representation); // Path Parameters must be strings!
break;
case Description.MinLength:
param.Schema.MinLength = Int32.Parse(representation);
break;
case Description.MaxLength:
param.Schema.MaxLength = Int32.Parse(representation);
break;
case Description.Pattern:
param.Schema.Pattern = representation;
break;
default:
throw new InvalidOperationException();
}
}
}
public class AddSettings : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
foreach (var param in operation.Parameters)
{
var actionParam = context.ApiDescription.ActionDescriptor.Parameters.First(p => p.Name == param.Name);
if (actionParam != null)
{
context.MethodInfo
.GetCustomAttributes(true)
.OfType<SwaggerPathParameterDescriptions>()
.Where(p => p.ParameterName == param.Name)
.ToList()
.ForEach(customAttribute =>
{
foreach (SwaggerParameterSchemaDescription description in customAttribute.GetSwaggerParameters())
{
description.ApplyTo(param);
}
});
}
}
}
}
}
并在启动中:
services.AddSwaggerGen(c => {
c.OperationFilter<AddSettings>();
然后使用:
[HttpPut("{containername}/contentfiles/{fileName}")]
[SwaggerPathParameterDescriptions("containername", "{\"MinLength\":3,\"MaxLength\":63,\"Pattern\":\"^[a-z0-9]+(-[a-z0-9]+)*$\"}")]
[SwaggerPathParameterDescriptions("fileName", "{\"MinLength\":1,\"MaxLength\":75,\"Pattern\":\"\\\\S\"}")]
[SwaggerResponseHeader(StatusCodes.Status201Created, "Location", "string", "Location of the newly created resource")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status503ServiceUnavailable)]
public ActionResult Put(string containername, string fileName, IFormFile fileData)
我的问题是它没有渲染。 :(我还有更多工作要做?还是我修改了错误的值?
答案 0 :(得分:1)
Swagger UI仅在使用showCommonExtensions: true
选项进行配置时才显示参数minLength
,maxLength
和pattern
。 This answer显示了如何通过Swashbuckle配置启用此选项。
但是,您必须等待Swagger UI的下一个版本才能使showCommonExtensions: true
选项适用于OpenAPI 3.0定义。该代码位于Swagger UI repository的master
分支中,但是尚未发布新版本。如果需要,您可以自己从master
分支构建Swagger UI,并在项目中使用生成的dist
资产来立即获得此功能。