Blazor中跨Razor页面传递JsonDocument,AppState应使用什么数据类型?
解决方案
方案一:将JSON转换为字符串存储(最简单)
这种方式适合仅需要传递JSON数据给JavaScript的场景,无需在.NET端保留JSON结构。
- 保持AppState的string类型不变:
public string? json { get; set; }
- 修改page1.razor代码,将JsonDocument转为原始JSON字符串:
private IBrowserFile _loadedFile; private async Task OnInputFileChange(InputFileChangeEventArgs e) { _loadedFile = e.File; var utf8Json = _loadedFile.OpenReadStream(maxAllowedSize: 1024 * 1024 * 10); try { // 使用using自动释放JsonDocument(它实现了IDisposable) using var jsonDocument = await JsonDocument.ParseAsync(utf8Json); // 获取原始JSON字符串 AppState.json = jsonDocument.RootElement.GetRawText(); } catch (JsonException ex) { Console.WriteLine(ex.Message); } }
- page2.razor无需修改:
protected override async Task OnAfterRenderAsync(bool firstRender) { await JSRuntime.InvokeVoidAsync("Create", AppState.json); }
JavaScript可以直接接收这个字符串并解析使用。
方案二:直接存储JsonDocument(适合需要在.NET端操作JSON结构)
如果需要在其他.NET代码中继续查询、修改JSON内容,可以将AppState的字段改为JsonDocument?类型,但要注意它是IDisposable类型,必须正确释放以避免内存泄漏。
- 修改AppState.cs,实现IDisposable管理JsonDocument生命周期:
public class AppState : IDisposable { private JsonDocument? _json; public JsonDocument? Json { get => _json; set { // 赋值前先释放旧的实例 _json?.Dispose(); _json = value; } } public void Dispose() { // 释放剩余的JsonDocument实例 _json?.Dispose(); GC.SuppressFinalize(this); } }
- 修改page1.razor代码直接赋值:
private IBrowserFile _loadedFile; private async Task OnInputFileChange(InputFileChangeEventArgs e) { _loadedFile = e.File; var utf8Json = _loadedFile.OpenReadStream(maxAllowedSize: 1024 * 1024 * 10); try { var jsonDocument = await JsonDocument.ParseAsync(utf8Json); AppState.Json = jsonDocument; } catch (JsonException ex) { Console.WriteLine(ex.Message); } }
- 修改page2.razor,将JsonDocument转为可传递给JS的格式:
如果需要传递JSON字符串给JS:
protected override async Task OnAfterRenderAsync(bool firstRender) { if (AppState.Json != null) { var jsonString = AppState.Json.RootElement.GetRawText(); await JSRuntime.InvokeVoidAsync("Create", jsonString); } }
如果希望直接传递JS对象(无需在JS端解析字符串),可以传递RootElement(JSRuntime会自动序列化它):
protected override async Task OnAfterRenderAsync(bool firstRender) { if (AppState.Json != null) { await JSRuntime.InvokeVoidAsync("Create", AppState.Json.RootElement); } }
内容的提问来源于stack exchange,提问作者Sarahrb
相关产品推荐
相关产品推荐

