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

如何让NSwag Studio生成的C#客户端包含默认参数?

问题描述

我在.NET Core 6中有如下控制器端点:

[HttpGet("GetAllMinimalCalculationDtoOfMaterialByLoggedinUser/{isExistingBuildingCalculation:bool?}", Name = "GetAllMinimalCalculationDtoOfMaterialByLoggedinUser")]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<MinimalCalculationDto>), (int)HttpStatusCode.OK),
    ProducesResponseType((int)HttpStatusCode.InternalServerError)]
public ActionResult GetAllMinimalCalculationDtoOfMaterialByLoggedinUser(bool isExistingBuildingCalculation = false)

使用Swagger和NSwag Studio v13.17.0.0生成C#客户端后,生成的代码未将该参数设为可选:

public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<MinimalCalculationDto>> GetAllMinimalCalculationDtoOfMaterialByLoggedinUserAsync(bool isExistingBuildingCalculation, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
    if (isExistingBuildingCalculation == null)
        throw new System.ArgumentNullException("isExistingBuildingCalculation");

    var urlBuilder_ = new System.Text.StringBuilder();
    urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/v1/Calculation/GetAllMinimalCalculationDtoOfMaterialByLoggedinUser/{isExistingBuildingCalculation}");
    urlBuilder_.Replace("{isExistingBuildingCalculation}", System.Uri.EscapeDataString(ConvertToString(isExistingBuildingCalculation, System.Globalization.CultureInfo.InvariantCulture)));

    var client_ = _httpClient;
    // 省略后续代码
}

生成的客户端中,isExistingBuildingCalculation参数没有默认值,且存在无意义的空检查(bool为值类型不可能为null)。我希望方法签名包含默认值false,允许不传参调用,同时保留传参能力。已开启NSwag Studio中的「Generate optional parameters」设置,但无效果。


解决方案

方案1:将路径参数改为查询参数(推荐)

路径参数在Swagger规范中默认被标记为必填项,即使控制器中设置了可选。将参数改为查询参数后,NSwag会正确识别其可选性:

[HttpGet("GetAllMinimalCalculationDtoOfMaterialByLoggedinUser", Name = "GetAllMinimalCalculationDtoOfMaterialByLoggedinUser")]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<MinimalCalculationDto>), (int)HttpStatusCode.OK),
    ProducesResponseType((int)HttpStatusCode.InternalServerError)]
public ActionResult GetAllMinimalCalculationDtoOfMaterialByLoggedinUser([FromQuery] bool isExistingBuildingCalculation = false)

重新生成客户端后,方法签名会自动带上= false的默认值,支持不传参调用。

方案2:强制标记路径参数为可选(需保留路径参数时使用)

如果必须保留路径参数结构,可通过Swagger过滤器修改参数的必填标记:

  1. 实现自定义Swagger操作过滤器:
public class OptionalPathParameterFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var optionalPathParams = context.MethodInfo.GetParameters()
            .Where(p => p.IsOptional && operation.Parameters.Any(param => param.Name == p.Name && param.In == ParameterLocation.Path));

        foreach (var param in optionalPathParams)
        {
            var swaggerParam = operation.Parameters.First(p => p.Name == param.Name);
            swaggerParam.Required = false;
            swaggerParam.Schema.Default = new OpenApiBoolean(param.DefaultValue);
        }
    }
}
  1. 在Program.cs中注册过滤器:
builder.Services.AddSwaggerGen(c =>
{
    c.OperationFilter<OptionalPathParameterFilter>();
});

更新Swagger文档后,重新用NSwag生成客户端,参数会被识别为可选,生成带默认值的方法签名。

方案3:调整NSwag Studio高级配置

在NSwag Studio的「C# Client」设置页切换到「Advanced」选项卡:

  • 确认「Generate optional parameters」已勾选
  • 勾选「Allow nullable value types」
  • 将「Default value handling」设置为「Use default values from schema」
    重新生成客户端,验证参数是否带默认值。

方案4:手动修改生成代码(临时方案)

如果上述方法均无效,可直接修改生成的客户端方法签名,添加默认值,并移除无意义的空检查:

public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<MinimalCalculationDto>> GetAllMinimalCalculationDtoOfMaterialByLoggedinUserAsync(bool isExistingBuildingCalculation = false, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
    var urlBuilder_ = new System.Text.StringBuilder();
    urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/v1/Calculation/GetAllMinimalCalculationDtoOfMaterialByLoggedinUser/{isExistingBuildingCalculation}");
    urlBuilder_.Replace("{isExistingBuildingCalculation}", System.Uri.EscapeDataString(ConvertToString(isExistingBuildingCalculation, System.Globalization.CultureInfo.InvariantCulture)));

    var client_ = _httpClient;
    // 后续代码不变
}

注意:每次重新生成客户端都需要重复修改,仅适合临时场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:20:28