为何GitHub Pages上的Blazor WebAssembly无法反序列化SortedSet?
Blazor WASM部署在GitHub Pages上的SortedSet反序列化异常问题
问题背景
我开发了一个部署在GitHub Pages上的Blazor WebAssembly站点,调用AWS云端API时需要反序列化包含SortedSet值的JSON数据。通过最小化代码复现发现:直接反序列化SortedSet会抛出异常,但本地Visual Studio运行无此问题。
复现代码
@page "/" <button onclick="@Deserialize">Deserialize</button> <br />Message: @message @code { private string message = "Nothing happened yet"; private void Deserialize() { try { SortedSet<int> sortedSet = JsonSerializer.Deserialize<SortedSet<int>>("[1,2,3]"); message = $"Deserialized SortedSet: {string.Join(",", sortedSet)}"; } catch (Exception e) { message = $"Deserialization ended up in an exception: {e}"; } } }
抛出的错误
System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, System.Collections.Generic.SortedSet`1[System.Int32] Path: $ | LineNumber: 0 | BytePositionInLine: 1. ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, System.Collections.Generic.SortedSet`1[System.Int32] Exception_EndOfInnerExceptionStack at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException ) at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type , Utf8JsonReader& , ReadStack& ) at System.Text.Json.Serialization.Converters.ISetOfTConverter`2[[System.Collections.Generic.SortedSet`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].CreateCollection(Utf8JsonReader& , ReadStack& , JsonSerializerOptions ) at System.Text.Json.Serialization.JsonCollectionConverter`2[[System.Collections.Generic.SortedSet`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , SortedSet`1& ) at System.Text.Json.Serialization.JsonConverter`1[[System.Collections.Generic.SortedSet`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , SortedSet`1& ) at System.Text.Json.Serialization.JsonConverter`1[[System.Collections.Generic.SortedSet`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& ) at System.Text.Json.JsonSerializer.ReadFromSpan[SortedSet`1](ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 ) at System.Text.Json.JsonSerializer.ReadFromSpan[SortedSet`1](ReadOnlySpan`1 , JsonTypeInfo ) at System.Text.Json.JsonSerializer.Deserialize[SortedSet`1](String , JsonSerializerOptions ) at SortedSetDeserializationDemo.Pages.Index.Deserialize()
临时修复方案
在反序列化SortedSet前先序列化任意SortedSet(可为空)。
异常相关奇怪现象
- 若将序列化代码放在反序列化尝试之后仍会报错
- 若序列化代码在绑定到其他按钮的方法中,即使不点击该按钮也不会报错
- 反序列化List时无异常
其他相关细节
- 该问题与Release/Debug配置无关,推测可能和JIT有关
- 可在Chrome和Edge浏览器中复现
- 使用.NET 6.0版本(测试过6.0.10和6.0.11)
问题解答
1. 异常原因
这是.NET 6 Blazor WebAssembly环境下的JIT编译缺陷导致的。Blazor WASM在WebAssembly运行时中,首次尝试反序列化SortedSet时,其无参构造函数未被正确JIT编译或加载。System.Text.Json的集合转换器在创建SortedSet实例时,无法找到可访问的构造函数,因此抛出DeserializeNoConstructor类型的NotSupportedException。
临时修复中提前执行SortedSet序列化的操作,会触发JIT编译器加载SortedSet的构造函数及相关类型信息,后续反序列化时就能正常找到构造函数完成实例初始化。
2. Bug归属
该Bug属于.NET Blazor WebAssembly的范畴,与GitHub Pages、浏览器无关。GitHub Pages仅提供静态文件托管服务,不影响代码运行逻辑;浏览器只是WebAssembly的运行容器,问题根源是.NET在WASM环境下的类型加载和JIT编译逻辑存在缺陷。该问题在.NET 7及后续版本已被官方修复,升级框架版本可彻底解决此问题。
内容的提问来源于stack exchange,提问作者EGeorge
相关产品推荐
相关产品推荐

