C# Core 3 WebAPI中QueryString参数值莫名变更问题求助
问题原因及解决方案
核心原因:二进制浮点数的精度限制
double类型属于二进制浮点数,它无法精确表示所有十进制小数。当你传递的-84.325648999999980这个十进制值被解析为double时,.NET会将其转换为最接近的二进制浮点数表示,而这个二进制值对应的十进制近似值就是-84.325648999999984。
这不是WebAPI的bug,而是浮点数的固有特性——大部分十进制小数在二进制体系中是无限循环的,只能用近似值存储。
验证方式
你可以直接在C#中测试这个转换逻辑:
double test = -84.325648999999980; Console.WriteLine(test); // 输出结果为 -84.325648999999984
解决方案
如果业务场景对精度要求严格(比如地理坐标计算),可以采用以下几种处理方式:
- 改用
decimal类型:decimal是十进制浮点数,能精确表示十进制小数,适合高精度场景。修改参数类型即可:[HttpGet] public async Task<List<NearbyLocation>> GetNearbyLocations( [FromQuery] decimal latitude, [FromQuery] decimal longitude, [FromQuery] long distance = 50000, [FromQuery] int quantity = 10 ) { // 若服务层需要double类型,可做显式转换;若服务也需高精度,建议同步修改参数类型 return await _geoTrackService.GetNearbyLocations( (double)latitude, (double)longitude, distance, quantity ); } - 字符串接收后手动转换:先以字符串形式接收参数,再手动解析为高精度类型,避免自动解析时的精度损失:
[HttpGet] public async Task<List<NearbyLocation>> GetNearbyLocations( [FromQuery] string latitude, [FromQuery] string longitude, [FromQuery] long distance = 50000, [FromQuery] int quantity = 10 ) { if (!decimal.TryParse(latitude, out var lat) || !decimal.TryParse(longitude, out var lon)) { // 处理参数格式错误 return BadRequest("Invalid coordinate format"); } return await _geoTrackService.GetNearbyLocations( (double)lat, (double)lon, distance, quantity ); } - 精度截断处理:如果允许一定误差,可在接收参数后将数值截断到需要的小数位数,比如保留14位小数:
longitude = Math.Round(longitude, 14);
内容的提问来源于stack exchange,提问作者Sabel
相关产品推荐
相关产品推荐

