Blazor WASM中传递JSON反序列化结果给组件报空引用异常如何解决
问题原因
该空引用异常由多个问题共同导致:
- 父组件首次渲染时数据源为空
父组件中shipments字段初始未赋值,OnInitializedAsync是异步方法,在API请求返回前组件会触发首次渲染,此时访问shipments.Items会直接触发空引用。 - JSON反序列化大小写不匹配
Blazor默认使用的System.Text.Json序列化器对大小写敏感,API返回的JSON字段为小驼峰命名(items、hash、totalCount等),但C#类属性为大驼峰命名(Items、Hash、TotalCount等),反序列化时无法匹配字段,会导致shipments.Items始终为null。 - byte[]类型反序列化逻辑缺失
ShipmentVm中Hash、PrevHash字段为byte[]类型,但API返回的是base64编码字符串,未配置序列化规则的前提下,这两个字段反序列化后始终为null。 - 子组件逻辑不严谨
子组件ShipmentsTable的Shipments参数未设置默认值,也没有做空判断就直接遍历;同时直接调用byte[]的ToString()方法只会返回类型全名,不会输出base64字符串,即使前面的问题解决也会显示异常。
解决步骤
- 父组件增加渲染条件,避免空值传递
父组件调用子组件时,先判断shipments是否加载完成,同时给字段设置初始值:
@if(shipments != null) { <ShipmentsTable Shipments="@shipments.Items"></ShipmentsTable> } else { <p>加载中...</p> } @code { // 给初始值避免空引用 private GetShipmentsResult shipments = new GetShipmentsResult(); protected override async Task OnInitializedAsync() { shipments = await HttpClient.GetFromJsonAsync<GetShipmentsResult>("https://localhost:5001/api/shipment?page=0", new JsonSerializerOptions { // 忽略字段大小写 PropertyNameCaseInsensitive = true }); } }
System.Text.Json原生支持将base64字符串反序列化为byte[],只要开启大小写忽略后就能正常转换。
- 修正子组件逻辑
首先给子组件参数设置默认值,再修正base64字段的输出逻辑:
@code { [Parameter] public List<ShipmentVm> Shipments { get; set; } = new List<ShipmentVm>(); }
遍历渲染时调整Hash字段的输出:
<tbody> @foreach (var shipment in Shipments) { <tr> <td>@shipment.IsDone</td> </tr> <tr> <td>@shipment.TimeStamp</td> </tr> <tr> <td>@(shipment.Hash != null ? Convert.ToBase64String(shipment.Hash) : string.Empty)</td> </tr> <tr> <td>@(shipment.PrevHash != null ? Convert.ToBase64String(shipment.PrevHash) : string.Empty)</td> </tr> } </tbody>
内容的提问来源于stack exchange,提问作者Kamil
相关产品推荐
相关产品推荐

