Blazor导航返回Razor页面时如何保留已绑定的C#变量数据
问题原因
Blazor组件为瞬态生命周期:每次导航离开页面时,当前组件实例会被销毁,组件内部定义的Eventlog_time/Eventlog_source/Eventlog_message等字段会随实例一同被回收;下次导航回页面时会创建全新的组件实例,字段均为初始空值,因此表格显示空白。
实现方案
最适配需求的方案是用作用域状态服务做内存缓存:服务生命周期和当前用户的会话绑定,切换页面不会销毁,只有用户关闭标签页、刷新页面、电路断开(Blazor Server场景)时才会释放,完全满足「返回页面保留上次读取结果,手动点Read才重新拉取」的要求,实现成本最低。
步骤1:创建缓存状态服务
新建独立的缓存类,专门存储EventLog相关数据:
public class EventLogCacheService { // 存储日志数据的字段 public string[]? Eventlog_time { get; set; } public string[]? Eventlog_source { get; set; } public string[]? Eventlog_message { get; set; } // 存储上次读取时间 public DateTime? Read_time { get; set; } // 标记是否已经读取过数据,避免空引用 public bool HasData => Eventlog_time != null && Eventlog_time.Length > 0; }
步骤2:注册服务到DI容器
打开项目的Program.cs,添加服务注册代码:
// 其他原有服务注册代码... builder.Services.AddScoped<EventLogCacheService>();
步骤3:修改Razor页面代码
在组件中注入缓存服务,删除原来组件自身定义的日志数组、读取时间字段,改用服务中存储的值;同时修复原有代码的数组越界、空引用bug:不要固定循环999次,要按数组实际长度渲染,未加载数据时不渲染表格行。
修改后的/wmi_event页面代码参考:
@page "/wmi_event" @inject EventLogCacheService LogCache <!-- 注入缓存服务 --> <h1>EventLog (Win Application Errors)</h1> <button class="btn btn-primary" @onclick="Read_EventLog">Read</button> @if (LogCache.Read_time.HasValue) { <p>Read Time= @LogCache.Read_time.Value.ToString("yyyy-MM-dd HH:mm:ss")</p> } <table border="1" cellpadding="6" cellspacing="0"> <tr> <th>Log Time</th> <th>Log Source</th> <th>Log Message</th> </tr> @if (LogCache.HasData) { <!-- 按数组实际长度循环,避免越界 --> for (var i = 0; i < LogCache.Eventlog_time!.Length; i++) { <tr> <td>@LogCache.Eventlog_time[i]</td> <td>@LogCache.Eventlog_source![i]</td> <td>@LogCache.Eventlog_message![i]</td> </tr> } } </table> @code { // 原组件内定义的Eventlog_time/Eventlog_source/Eventlog_message/Read_time字段全部删除 private async Task Read_EventLog() { // 保留原有WMI读取远程日志逻辑 // 读取到结果后直接赋值给缓存服务属性,不要给组件自身字段赋值 var (times, sources, messages) = await WmiHelper.ReadRemoteEventLogAsync(); // 替换为你自己的WMI读取方法 LogCache.Eventlog_time = times; LogCache.Eventlog_source = sources; LogCache.Eventlog_message = messages; LogCache.Read_time = DateTime.Now; } }
可选扩展:刷新页面也保留数据
如果需要用户手动刷新浏览器页面后也保留上次读取结果,只需要在Read_EventLog方法拿到数据后,额外把数据序列化存入浏览器localStorage,组件初始化时先从localStorage读数据回填到缓存服务即可,不需要改动现有缓存逻辑。
注意:
- 不要用静态变量存储这类用户私有数据,Blazor Server场景下静态变量为应用全局共享,会导致不同用户看到彼此的日志数据,存在数据泄漏风险。
- 原有代码固定循环999次的写法存在数组越界异常风险,必须改为按数组实际长度循环,同时增加数据存在性判断,避免首次进入页面未读取数据时触发空引用错误。
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

