异步使用另一对象更新目标对象触发空引用异常问题排查
问题根因
该NullReferenceException的触发点有两个高概率场景:
OnInitializedAsync执行时,[Parameter]标记的CustomerId还未完成父组件传值,仍为默认值0,调用dataService.Get1056StatusById(CustomerId)返回null,后续访问Statuses.CustomerId时触发空引用UpdateValues方法中调用查询接口返回null,直接访问PreviousStatuses的属性赋值时触发空引用
修复方案
1. 调整初始化时机+增加空值校验,避免访问未初始化的对象
修改后的代码如下:
[Parameter] public int CustomerId { get; set; } [CascadingParameter] public Task<AuthenticationState> AuthState { get; set; } public Status Statuses; public Status PreviousStatuses; public Dspd1056Status StatusToAdd = new Dspd1056Status(); public Customer customer; public int AccountStatusId = 0; // 初始化逻辑挪到OnParametersSetAsync,保证Parameter已完成赋值 protected override async Task OnParametersSetAsync() { // 先判断CustomerId有效再调用接口 if (CustomerId <= 0) return; Statuses = await dataService.Get1056StatusById(CustomerId); // 校验Statuses不为空再执行后续逻辑 if (Statuses == null || string.IsNullOrEmpty(Statuses.CustomerId)) { // 可自行添加数据不存在的提示逻辑 return; } Console.WriteLine(Statuses.CustomerId); await UpdateValues(Statuses.CustomerId); } async Task UpdateValues(string id) { if (!int.TryParse(id, out int customerId)) { // 可自行添加ID格式错误的处理逻辑 return; } PreviousStatuses = await dataService.Get1056StatusById(customerId); // 校验PreviousStatuses不为空再赋值 if (PreviousStatuses == null) { // 可自行添加无对应状态数据的处理逻辑 return; } StatusToAdd.AccountCurrent = PreviousStatuses.AccountCurrent; StatusToAdd.StartDate = PreviousStatuses.StartDate; StatusToAdd.EndDate = PreviousStatuses.EndDate; StatusToAdd.Units = PreviousStatuses.Units; StatusToAdd.Ppc = PreviousStatuses.Ppc; StatusToAdd.EndStatus = PreviousStatuses.EndStatus; StatusToAdd.ContinuallyFunded = PreviousStatuses.ContinuallyFunded; StatusToAdd.AnnualUnits = PreviousStatuses.AnnualUnits; StatusToAdd.Elg = PreviousStatuses.Elg; StatusToAdd.ReceiptDate = PreviousStatuses.ReceiptDate; StatusToAdd.RahTripsFunded = PreviousStatuses.RahTripsFunded; StatusToAdd.Rate = PreviousStatuses.Rate; StatusToAdd.AccountTotal = PreviousStatuses.AccountTotal; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { if (CustomerId != 0) { customer = await dataService.GetCustomerById(CustomerId); StateHasChanged(); } } }
补充说明
Blazor组件的参数绑定在OnInitializedAsync执行完成后才会结束,部分场景下该阶段CustomerId还未收到父组件传值,默认值0会导致查询返回空数据。所有接口返回对象都增加空值校验,能从根源避免空引用异常。
内容的提问来源于stack exchange,提问作者Brsn
相关产品推荐
相关产品推荐

