Blazor WASM中Snowflake ID传递WebAPI时值变更问题求助
解决Snowflake ID在Blazor WASM与WebAPI传递时的精度丢失问题
问题核心:JSON标准的数值类型仅能精确表示≤2^53的整数,而Snowflake ID是64位的long类型(远超2^53),序列化/反序列化时会被近似处理,导致数值变更。
解决方案1:通过Newtonsoft.Json转换器强制将Long类型序列化为字符串
自定义Json转换器,让所有long类型字段在序列化时转为字符串,反序列化时转回long:
- 实现自定义转换器:
public class LongToStringConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(long) || objectType == typeof(long?); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.Value is string str && long.TryParse(str, out var result)) { return result; } return reader.Value; } }
- 修改客户端序列化代码:
var serializerSettings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new LongToStringConverter() } }; string serializedData = JsonConvert.SerializeObject(request, serializerSettings);
- WebAPI端同步配置:
在WebAPI的启动配置中全局启用该转换器:
services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new LongToStringConverter()); });
解决方案2:直接将实体类中的Snowflake ID字段改为字符串类型
- 修改实体类定义:
把Orders、POSOrderRequest等类中的订单ID字段类型从long改为string:
public class Orders { // 原:public long OrderId { get; set; } public string OrderId { get; set; } // 其他字段... }
- 生成Snowflake ID时直接转为字符串:
string orderId = snowflakeGenerator.GenerateId().ToString();
- 数据库兼容:
若数据库中该字段为bigint类型,无需修改(字符串可直接存入并匹配查询);若要更严谨,可改为varchar(20)类型。
解决方案3:使用System.Text.Json配置(若项目支持)
如果项目切换为System.Text.Json序列化,可通过配置强制将long类型序列化为字符串:
- 客户端序列化配置:
var jsonOptions = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.WriteAsString }; string serializedData = JsonSerializer.Serialize(request, jsonOptions);
- WebAPI端全局配置:
services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.WriteAsString; });
关键注意事项
- 必须保证客户端与服务端使用完全一致的序列化规则,否则会出现序列化/反序列化不匹配的问题。
- 之前手动转字符串无效,是因为实体类字段仍为long类型,序列化框架会自动将其转为数值类型,必须通过转换器或字段类型修改来强制转为字符串。
内容的提问来源于stack exchange,提问作者ramesh
相关产品推荐
相关产品推荐

