如何在Azure Functions OpenAPI扩展中添加只读属性?
搞定Azure Functions OpenAPI 3.0的只读属性控制
方案1:直接用扩展包自带的[OpenApiReadOnly]属性
别慌,这个OpenApi扩展包其实已经支持只读属性的标注,只是你看的文档没明说。直接用Microsoft.Azure.WebJobs.Extensions.OpenApi.Attributes命名空间下的[OpenApiReadOnly],效果和旧版[ReadOnly(true)]完全一致:
- 像POST、PUT这类写操作,标了这个属性的字段会自动从请求体里消失
- GET这类读操作,字段会正常显示在响应里
改完的模型示例:
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Attributes; public class ThingModel { [Display(Name = "Thing Id", Description = "Thing Model Id")] [OpenApiReadOnly] // 替换原来的[ReadOnly(true)] public Guid? Id { get; set; } [Display(Name = "Thing Name", Description = "Name of Thing")] [OpenApiRequired] // 对应旧版的[Required(HttpMethodType.Post)],扩展包会自动识别请求方法 public string Name { get; set; } [Display(Name = "Thing Description", Description = "Description of Thing")] public string Description { get; set; } }
方案2:自定义筛选器(针对特殊场景)
如果需要更细的控制——比如只在特定HTTP方法里隐藏字段,就自己写个Schema筛选器:
- 先定义自定义属性:
[AttributeUsage(AttributeTargets.Property)] public class ReadOnlyForHttpMethodAttribute : Attribute { public HttpMethod[] ExcludedMethods { get; } public ReadOnlyForHttpMethodAttribute(params HttpMethod[] excludedMethods) { ExcludedMethods = excludedMethods; } }
- 实现筛选逻辑:
using Microsoft.OpenApi.Models; using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions; using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions; public class ReadOnlySchemaFilter : IOpenApiSchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (context.ApiOperation is null || schema.Properties is null) return; var httpMethod = new HttpMethod(context.ApiOperation.Method.ToString().ToUpper()); var propertiesToRemove = context.Type.GetProperties() .Where(p => p.GetCustomAttribute<ReadOnlyForHttpMethodAttribute>() is { } attr && attr.ExcludedMethods.Contains(httpMethod)) .Select(p => p.Name.ToCamelCase()) // 扩展包默认用驼峰命名,注意匹配 .ToList(); foreach (var prop in propertiesToRemove) { schema.Properties.Remove(prop); } } }
注册筛选器:
- 要是用的隔离进程模型,在Program.cs里添加:
var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices(services => { services.AddOpenApiCore() .AddSchemaFilter<ReadOnlySchemaFilter>(); }) .Build(); host.Run(); - 要是进程内模型,就在Startup.cs的ConfigureServices里添加:
services.AddOpenApi() .AddSchemaFilter<ReadOnlySchemaFilter>();
- 要是用的隔离进程模型,在Program.cs里添加:
模型中使用自定义属性:
public class ThingModel { [Display(Name = "Thing Id", Description = "Thing Model Id")] [ReadOnlyForHttpMethod(HttpMethod.Post, HttpMethod.Put)] // 只在POST/PUT操作里隐藏该字段 public Guid? Id { get; set; } // 其他属性正常编写即可 }
额外提醒
OpenApiRequired比旧版的Required属性省心,不用指定HTTP方法,它会自动根据请求类型判断是否标记为必填。
内容的提问来源于stack exchange,提问作者DDevs
相关产品推荐
相关产品推荐

