You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swagger中为C#参数添加占位符而非默认值?

在Swagger中为C#接口参数添加占位符而非预填默认值

你当前使用[DefaultValue]特性会让Swagger的"Try it out"自动预填参数值,不符合仅显示灰色提示的需求。以下是实现类似HTML输入框占位符效果的方案:

方案一:自定义占位符特性+Swagger过滤器

1. 创建自定义占位符特性

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public class SwaggerPlaceholderAttribute : Attribute
{
    public string Placeholder { get; }

    public SwaggerPlaceholderAttribute(string placeholder)
    {
        Placeholder = placeholder;
    }
}

2. 实现Swagger操作过滤器

这个过滤器会读取自定义特性的值,添加到Swagger Schema的扩展字段中:

public class SwaggerPlaceholderFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 处理URL查询参数
        foreach (var parameter in operation.Parameters)
        {
            var paramInfo = context.ApiDescription.ParameterDescriptions
                .FirstOrDefault(p => p.Name == parameter.Name);
            if (paramInfo?.ParameterInfo != null)
            {
                var placeholderAttr = paramInfo.ParameterInfo
                    .GetCustomAttribute<SwaggerPlaceholderAttribute>();
                if (placeholderAttr != null)
                {
                    parameter.Schema.Extensions.Add("x-placeholder", new OpenApiString(placeholderAttr.Placeholder));
                }
            }
        }

        // 处理请求体中的属性
        if (operation.RequestBody != null && operation.RequestBody.Content.TryGetValue("application/json", out var content))
        {
            var schema = content.Schema;
            if (schema.Properties != null)
            {
                foreach (var property in schema.Properties)
                {
                    var propertyInfo = context.ApiDescription.ActionDescriptor.Parameters
                        .SelectMany(p => p.ParameterType.GetProperties())
                        .FirstOrDefault(p => p.Name == property.Key);
                    if (propertyInfo != null)
                    {
                        var placeholderAttr = propertyInfo.GetCustomAttribute<SwaggerPlaceholderAttribute>();
                        if (placeholderAttr != null)
                        {
                            property.Value.Extensions.Add("x-placeholder", new OpenApiString(placeholderAttr.Placeholder));
                        }
                    }
                }
            }
        }
    }
}

3. 注册过滤器

在Program.cs或Startup.cs中注册这个过滤器:

builder.Services.AddSwaggerGen(c =>
{
    c.OperationFilter<SwaggerPlaceholderFilter>();
});

4. 配置Swagger UI读取扩展字段

创建自定义JavaScript脚本,让Swagger UI识别x-placeholder扩展并设置为输入框的占位符:

  1. 在wwwroot目录下创建swagger-custom.js,内容如下:
window.addEventListener('load', function() {
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            if (mutation.addedNodes.length) {
                mutation.addedNodes.forEach(node => {
                    if (node.tagName === 'INPUT' && node.parentElement) {
                        const paramName = node.parentElement.querySelector('.parameter__name')?.textContent.trim();
                        if (!paramName) return;

                        let placeholder = null;
                        const swaggerPaths = window.ui.getModel().schema.paths;
                        Object.values(swaggerPaths).forEach(path => {
                            Object.values(path).forEach(operation => {
                                // 检查查询参数
                                if (operation.parameters) {
                                    const param = operation.parameters.find(p => p.name === paramName);
                                    if (param?.['x-placeholder']) placeholder = param['x-placeholder'];
                                }
                                // 检查请求体属性
                                if (operation.requestBody?.content?.['application/json']?.schema?.properties) {
                                    const prop = operation.requestBody.content['application/json'].schema.properties[paramName];
                                    if (prop?.['x-placeholder']) placeholder = prop['x-placeholder'];
                                }
                            });
                        });

                        if (placeholder) node.setAttribute('placeholder', placeholder);
                    }
                });
            }
        });
    });

    observer.observe(document.querySelector('.swagger-ui'), { childList: true, subtree: true });
});
  1. 在Swagger UI配置中引入该脚本:
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "你的API名称 V1");
    c.InjectJavascript("/swagger-custom.js");
});

5. 使用示例

// 接口参数使用
[HttpGet("user-info")]
public IActionResult GetUserInfo([SwaggerPlaceholder("请输入用户ID")] string userId)
{
    return Ok(new { UserId = userId });
}

// 请求体模型使用
public class UserCreateRequest
{
    [SwaggerPlaceholder("请输入用户名")]
    public string Username { get; set; }

    [SwaggerPlaceholder("请输入注册邮箱")]
    public string Email { get; set; }
}

方案二:复用[Display]特性的Prompt属性

如果你不想创建自定义特性,可以直接用.NET内置的[Display(Prompt = "...")]特性,只需要修改过滤器读取Prompt值:

1. 修改过滤器

public class DisplayPromptPlaceholderFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 处理查询参数
        foreach (var parameter in operation.Parameters)
        {
            var paramDesc = context.ApiDescription.ParameterDescriptions.FirstOrDefault(p => p.Name == parameter.Name);
            if (paramDesc != null)
            {
                var displayAttr = paramDesc.ParameterInfo.GetCustomAttribute<DisplayAttribute>();
                if (displayAttr != null && !string.IsNullOrEmpty(displayAttr.Prompt))
                {
                    parameter.Schema.Extensions.Add("x-placeholder", new OpenApiString(displayAttr.Prompt));
                }
            }
        }

        // 处理请求体属性
        if (operation.RequestBody?.Content.TryGetValue("application/json", out var content) == true)
        {
            var schema = content.Schema;
            if (schema.Properties != null)
            {
                foreach (var prop in schema.Properties)
                {
                    var propInfo = context.ApiDescription.ActionDescriptor.Parameters
                        .SelectMany(p => p.ParameterType.GetProperties())
                        .FirstOrDefault(p => p.Name == prop.Key);
                    if (propInfo != null)
                    {
                        var displayAttr = propInfo.GetCustomAttribute<DisplayAttribute>();
                        if (displayAttr != null && !string.IsNullOrEmpty(displayAttr.Prompt))
                        {
                            prop.Value.Extensions.Add("x-placeholder", new OpenApiString(displayAttr.Prompt));
                        }
                    }
                }
            }
        }
    }
}

2. 使用示例

[HttpGet("user-info")]
public IActionResult GetUserInfo([Display(Prompt = "请输入用户ID")] string userId)
{
    return Ok(new { UserId = userId });
}

后续的Swagger UI配置和脚本和方案一完全一致。

内容的提问来源于stack exchange,提问作者Kayomez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:15:41