Blazor Server事件执行顺序错误 QuoteModel未实例化空引用解决方法
Blazor Server 异步生命周期导致视图提前渲染空引用问题解决方案
问题根因
Blazor Server 组件执行异步生命周期方法(如OnInitializedAsync)时,只要方法内遇到第一个未执行完成的await任务,就会暂时让出执行线程,提前触发一次组件渲染。
你的代码中第一个await操作是_role = await Authorization.GetCurrentUserRoleAsync();,该任务执行完成返回时,组件就会触发渲染,此时后续的QuoteModel = await QuotesDb.GetQuoteByIdAsync(_role, QuoteId);还未执行,QuoteModel为默认null值,视图中直接访问QuoteModel.Date就会抛出空引用异常。
解决方案
方案1:视图层增加空值判断(最推荐,符合Blazor开发规范)
Blazor 组件本身就会因为状态变更多次触发渲染,在视图中对未加载完成的模型做空判断,同时展示加载状态,是最稳妥的实现方式,不需要改动后端生命周期逻辑,还能给用户明确的加载反馈:
@* 模型未加载完成时展示加载占位 *@ @if (QuoteModel == null) { <div>报价数据加载中...</div> } else if ((DateTime.Now - QuoteModel.Date).TotalDays > 60) { @* 原有业务逻辑 *@ }
方案2:提前初始化模型默认值
如果不想增加视图分支判断,可以在非异步的生命周期方法(如OnInitialized)或者类构造函数中,先给QuoteModel赋值一个非空的默认实例,等异步请求完成后再替换为真实数据。需要注意默认实例的属性值不要触发错误的业务逻辑判断:
// .razor.cs 代码后置文件 protected override void OnInitialized() { // 先给默认值,避免第一次渲染时空引用 QuoteModel = new QuoteModel { Date = DateTime.MinValue }; } protected override async Task OnInitializedAsync() { _role = await Authorization.GetCurrentUserRoleAsync(); QuoteModel = await QuotesDb.GetQuoteByIdAsync(_role, QuoteId); }
避坑提醒
不要为了避免提前渲染,在异步生命周期方法中使用.Result、.Wait()等方式同步阻塞等待任务,Blazor Server 采用单线程同步上下文,这种写法会直接导致应用死锁。
内容的提问来源于stack exchange,提问作者David Shochet
相关产品推荐
相关产品推荐

