ASP.NET Core中HttpGet请求Swagger里Json Ignore不生效问题
问题
在ASP.NET Core Web API中,我为Swashbuckle Swagger配置了Json Ignore,实现代码如下:
public class QueryChequeBookRequestDto : GetCreateChequeDetailDto { [Required(ErrorMessage = "Account Number field is required.")] [JsonProperty("AccountNumber")] public string AccountNumber { get; set; } } public class GetCreateChequeDetailDto { [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonProperty("AdmissionNumber")] public string AdmissionNumber { get; set; } = null; [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonProperty("SchoolCode")] public string SchoolCode { get; set; } = null; }
控制器代码:
[Produces("application/json")] [Consumes("application/json")] [Route("api/[controller]")] [ApiController] public class ChequeBookController : ControllerBase { private readonly IChequeBooksServices _chequeBooksServices; public ChequeBookController( IChequeBooksServices chequeBooksServices ) { _chequeBooksServices = chequeBooksServices; } [HttpGet("QueryChequeBook")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task<IActionResult> GetQueryChqueBookAsync([FromQuery] QueryChequeBookRequestDto chequeBookDto) { var result = await _chequeBooksServices.GetQueryChequeBookAsync(chequeBookDto); return StatusCode(result.StatusCode, result); } }
我希望AdmissionNumber和SchoolCode字段完全隐藏,该配置在HttpPost请求的Swagger文档中生效,但在HttpGet请求中无效,这两个字段仍显示在Swagger里。请问为何会出现这种情况?该如何解决?
问题原因
核心原因是**JsonIgnore只控制JSON序列化/反序列化行为,对URL查询参数的模型绑定逻辑不生效**:
- HttpPost请求中,参数通过JSON请求体传递,Swagger遵循JSON序列化规则,
JsonIgnore会让Swagger隐藏这些字段; - HttpGet请求中,参数通过URL查询字符串传递,此时Swagger基于ASP.NET Core的模型绑定规则生成文档,
JsonIgnore不会被模型绑定系统识别,所以这两个字段会被当成查询参数显示出来。
解决方法
方案1:使用[BindNever]特性
[BindNever]是ASP.NET Core模型绑定的特性,用来告诉模型绑定系统忽略该字段,Swashbuckle会识别这个特性并在文档中隐藏对应的查询参数。
修改DTO代码:
public class GetCreateChequeDetailDto { [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonProperty("AdmissionNumber")] [BindNever] // 添加该特性 public string AdmissionNumber { get; set; } = null; [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonProperty("SchoolCode")] [BindNever] // 添加该特性 public string SchoolCode { get; set; } = null; }
方案2:拆分专用DTO
为Get请求单独创建不含敏感字段的DTO,避免共用DTO带来的规则冲突,这种方式更清晰,也符合单一职责原则:
- 创建Get请求专用DTO:
public class QueryChequeBookGetRequestDto { [Required(ErrorMessage = "Account Number field is required.")] [JsonProperty("AccountNumber")] public string AccountNumber { get; set; } }
- 修改控制器方法参数:
[HttpGet("QueryChequeBook")] public async Task<IActionResult> GetQueryChqueBookAsync([FromQuery] QueryChequeBookGetRequestDto chequeBookDto) { // 按需转换为业务层需要的DTO var request = new QueryChequeBookRequestDto { AccountNumber = chequeBookDto.AccountNumber }; var result = await _chequeBooksServices.GetQueryChequeBookAsync(request); return StatusCode(result.StatusCode, result); }
方案3:自定义Swagger过滤器
通过Swashbuckle的IOperationFilter自定义逻辑,手动隐藏指定的查询参数:
- 创建过滤器类:
public class HideQueryParamsFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) return; // 指定要隐藏的参数名称 var paramsToHide = new[] { "AdmissionNumber", "SchoolCode" }; operation.Parameters = operation.Parameters .Where(p => !paramsToHide.Contains(p.Name)) .ToList(); } }
- 在
Program.cs中注册过滤器:
builder.Services.AddSwaggerGen(c => { // 注册自定义过滤器 c.OperationFilter<HideQueryParamsFilter>(); });
内容的提问来源于stack exchange,提问作者Ayobamilaye
相关产品推荐
相关产品推荐

