为何ASP.NET MVC传入空白字符的查询参数会变为Null?
ASP.NET Core 查询参数空白字符被解析为Null的问题
问题场景
接手一个停滞一年的未完成功能,原作者已离职,涉及的API端点和模型代码如下:
API端点代码
[HttpGet("search")] public ActionResult GetId([FromQuery] SearchQuery query) { if (string.IsNullOrEmpty(query.PartialDescription) && string.IsNullOrEmpty(query.PartialReference)) return BadRequest(new { Reason = "Cannot search as no string values were supplied" }); // 执行查询逻辑 }
模型代码
public class SearchQuery { public SearchQuery(); [MaxLength(50, ErrorMessage = "Invalid Reference. May not exceed 50 characters.")] public string PartialReference { get; set; } [MaxLength(250, ErrorMessage = "Invalid Description. May not exceed 250 characters.")] public string PartialDescription { get; set; } }
原本觉得守卫子句用string.IsNullOrEmpty是疏漏,改成string.IsNullOrWhiteSpace后单元测试通过,但用Swagger测试时,输入单个空格作为参数值(Swagger生成的URL包含%20编码),端点接收到的参数却是Null,而非预期的单个空格。
原因
这是ASP.NET Core默认模型绑定的内置行为:框架会自动修剪查询字符串中的空白字符,并将纯空白的字符串值转换为null。这个逻辑来自QueryStringValueProvider,和验证中间件无关。
若需接收空白字符的配置方案
如果业务场景确实需要保留纯空白的参数值,可通过以下方式配置:
1. 全局关闭空白修剪
在Program.cs中配置MVC选项,全局禁用字符串自动修剪:
builder.Services.AddControllers(options => { // 全局关闭所有字符串参数的空白修剪 options.TrimStrings = false; });
这个配置适用于.NET 6及以上版本,会对所有查询参数、表单参数的字符串生效。
2. 针对单个模型属性配置
如果只需要特定属性保留空白字符,可在模型属性上添加[DisplayFormat(ConvertEmptyStringToNull = false)],同时确保全局修剪未开启(或针对该属性单独处理):
public class SearchQuery { public SearchQuery(); [MaxLength(50, ErrorMessage = "Invalid Reference. May not exceed 50 characters.")] [DisplayFormat(ConvertEmptyStringToNull = false)] public string PartialReference { get; set; } [MaxLength(250, ErrorMessage = "Invalid Description. May not exceed 250 characters.")] [DisplayFormat(ConvertEmptyStringToNull = false)] public string PartialDescription { get; set; } }
该属性会让框架将纯空白字符串保留为空白值,而非转换为null。
内容的提问来源于stack exchange,提问作者Steve Crane
相关产品推荐
相关产品推荐

