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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:25:20