c# 关于long类型较大数据从接口返回出来时值被变更的问题

背景:

一个值为830543498159296850的Long类型数据接口返回给前端时值变成了830543498159296900 (以Number的类型返回,即{uid:830543498159296850})

 

原因:

在于 JavaScript 的 Number 类型(即 IEEE 754 双精度浮点数)的“安全整数”上限

1. 安全整数范围(2^53 规则)

JavaScript 中的 Number 类型能精确表示的最大整数是 2^53 - 1,即:

9,007,199,254,740,991(约 9 千万亿,也就是 16 位数字)

只要整数在 [-2^53, 2^53] 这个范围内,JS 就能做到 一一对应、精确无误

 

总结:Number数据在返回到前端时,若为16为就会被准确返回,但大于16为查过安全范围,只能采用最近的浮点数近似值(即四舍五入到最接近的 128 的倍数)

对比我的18位值就会变成...900

 

解决方法:

 将此值以字符串的方式返回给前端

如增加一个Long类型处理的转换器

public class LongToStringJsonConverter : JsonConverter<long>
{
    public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var flag = long.TryParse(reader.GetString(), out long ret);
            if (flag)
                return ret;
            return 0;
        }
        return reader.GetInt64();
    }

    public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
    {
         writer.WriteStringValue(value.ToString()); // 序列化时全部变成字符串
    }
}

注入

builder.Services.AddControllers(options =>
{
    options.Filters.Add(typeof(AuthorizationFilter));
    options.Filters.Add(typeof(PermissionFilter));
    //添加异常捕获
    options.Filters.Add(typeof(CustomExceptionCodeFilter));
}).AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new DateTimeOffsetJsonConverter());
    options.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());
    options.JsonSerializerOptions.Converters.Add(new LongToStringJsonConverter());
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

 

 注:这种后端处理的方式会将所有的Long类型在响应给前端时都处理成字符串,如果只是部分需要这样处理可以考虑前端来处理这个问题

 

 

 

posted @ 2026-07-30 15:42  流年sugar  阅读(7)  评论(0)    收藏  举报