如何让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过滤器修改参数的必填标记:
- 实现自定义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); } } }
- 在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
相关产品推荐
相关产品推荐

