我正在使用 Swashbuckle 和 Swagger UI 自动生成 API 文档。
我的人员端点使用以下 PersonViewmodel:
public int? ID { get; set; }
public string Name { get; set; }
我的端点方法采用 PersonViewmodel 作为主体,并使用 IActionResult 返回 PersonViewmodel。但是,我不希望用户定义由业务逻辑生成的 ID。在代码中,如果设置了 ID,它将被忽略。
如何更改 Swagger UI,使其不在正文输入的示例值中显示 ID,但仍显示响应的示例值的 ID?
我发现了很多从 Swagger UI 中完全删除属性的方法,例如
[JsonIgnore]
或将属性设置为 internal
或 private
。但是如何从 swagger 中的输入示例中删除属性,但将其保留在输出/响应示例中?
请使用属性上方的属性
[BindNever]
,例如
[BindNever]
public int? Id {get;set;}
另外,请检查您是否使用 Newtonsoft.Json 进行序列化,这可能是您的 System.Text 的
JsonIgnore
属性不起作用的原因。
现在有更好的方法了。有两件事你需要做
[SwaggerSchema(ReadOnly = true)]
public int Id { get; set; }
builder.Services.AddSwaggerGen(options =>
{
options.EnableAnnotations();
});
在文档
中查看更多相关信息我尝试了很多不同的选择,但没有一个适合我的需求。 根据 GitHub issues,
[SwaggerSchema(ReadOnly = true)]
似乎不起作用;使用架构处理器也不起作用,尤其是在处理 OData 控制器时。
我最终使用
IDocumentFilter
解决了这个问题。
文档过滤器:
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
/// <summary>
/// Makes sure readonly parameters are not considered while creating/updating/deleting an entity
/// </summary>
public class SwaggerRemoveReadonlyParameters_DocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var apiDesc in context.ApiDescriptions)
{
// Ignore GET method (we DO want readonly parameters to be displayed, in this case)
if (apiDesc.HttpMethod == "GET")
continue;
var readonlyParameters = apiDesc.ParameterDescriptions.Where(ShouldBeFilteredOut);
foreach (var readonlyParameter in readonlyParameters.ToArray())
apiDesc.ParameterDescriptions.Remove(readonlyParameter);
}
}
private static bool ShouldBeFilteredOut(ApiParameterDescription parameter)
{
// Only consider model binding
if (parameter.Source.DisplayName != "ModelBinding")
return false;
// Identify read only properties... (sometimes Swashbuckle/Swagger shows them anyway, especially in OData controllers)
if (parameter.ModelMetadata?.IsReadOnly == true)
return true;
if (parameter.ModelMetadata is not DefaultModelMetadata modelMetadata)
return false;
// ...and properties/fields explicitly marked as readonly by decorating them with the [SwaggerReadOnly] attribute
if (modelMetadata.Attributes.Attributes.Any(a => a is SwaggerReadOnlyAttribute))
return true;
return false;
}
}
属性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class SwaggerReadOnlyAttribute : Attribute { }
通过以下方式注册您的文档过滤器:
Services.AddSwaggerGen(options => options.DocumentFilter<SwaggerRemoveReadonlyParameters_DocumentFilter>());
像这样装饰你的只读属性:
public class MyEntity
{
[SwaggerReadOnly] // Hidden by the Document Filter
public Guid Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
[SwaggerReadOnly] // Hidden by the Document Filter
public DateTime LastModified { get; set; }
// Automatically hidden by the Document Filter
public bool HasDescription => !string.IsNullOrEmpty(Description);
}