.net 计算或调用后Blazor渲染

.net 计算或调用后Blazor渲染,.net,blazor,.net-5,.net,Blazor,.net 5,在Blazor中迈出第一步 我的页面Test.razor有一个简单的网格: <table class="table"> <thead> <tr>Message</tr> </thead> <tbody> @foreach (var exception in Exceptions) { <tr>exc

在Blazor中迈出第一步

我的页面Test.razor有一个简单的网格:

<table class="table">
    <thead>
        <tr>Message</tr>
    </thead>
    <tbody>
        @foreach (var exception in Exceptions)
        {
            <tr>exception.Message</tr>
        }
    </tbody>
</table>

消息
@foreach(异常中的var异常)
{
例外消息
}
我的逻辑是:

公共部分类测试

{
    public List<TestEventModel> Exceptions { get; set; }


    protected override async void OnInitialized()
    {
        var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
        Exceptions = JsonConvert.DeserializeObject<List<TestEventModel>>(await exceptionsResponse);

    }
}
{
公共列表异常{get;set;}
受保护的重写异步void OnInitialized()
{
var exceptionResponse=(wait http.GetAsync(“TestController”)).Content.ReadAsStringAsync();
Exceptions=JsonConvert.DeserializeObject(等待ExceptionResponse);
}
}
问题:未处理的异常呈现组件:对象引用未设置为对象的实例

线路上发生异常:

@foreach(异常中的var异常)

但根据生命周期,它应该仅在执行初始化后才开始渲染:

例如,如果我确实在构造函数中初始化了列表,问题就不存在了,但是列表当然是空的,并且不会显示http调用的结果。

为什么不初始化异常?
async OnInitialized
(和
OnInitializedAsync
;如果您正在执行HTTP请求之类的异步工作,则应使用此选项,而不是
OnInitialized
)在呈现之前开始,但
wait
取消阻止执行链,允许页面在资产之前呈现(即问题中的
异常
)已加载

例子 我创建了一个测试页面,记录每个生命周期事件的时间顺序。特别要注意的是
OnInitialized
方法:

protected override async void OnInitialized()
{
记录(“->OnInitialized”);
//注意:我不提倡你使用任务。运行。。。
//这是为了模拟对外部源的异步调用!
Data=wait Task.Run(()=>newlist{“Hello there”});
StateHasChanged();//并非总是必需的…请参阅下面的链接
base.OnInitialized();
记录(“初始化”);
base.OnInitialized();
记录(“为什么不初始化异常?
async OnInitialized
(和
OnInitializedAsync
;如果您正在执行HTTP请求之类的异步工作,则应使用此选项,而不是
OnInitialized
)在呈现之前开始,但
wait
取消阻止执行链,允许页面在资产之前呈现(即问题中的
异常
)已加载

例子 我创建了一个测试页面,记录每个生命周期事件的时间顺序。特别要注意
OnInitialized
方法:

protected override async void OnInitialized()
{
记录(“->OnInitialized”);
//注意:我不提倡你使用任务。运行。。。
//这是为了模拟对外部源的异步调用!
Data=wait Task.Run(()=>newlist{“Hello there”});
StateHasChanged();//并非总是必需的…请参阅下面的链接
base.OnInitialized();
记录(“初始化”);
base.OnInitialized();

Record(“Blazor在多个过程中呈现,您所经历的是绝对正常的。我的理解是,即使页面等待异步数据填充(复杂的数据库搜索等),也会加载大部分页面

有两种方法可以避免在async init上抛出null引用:

1.检查空值。别担心,组件将初始化所有内容,并在第二遍正确渲染

@if (Exceptions is not null){
    foreach (var exception in Exceptions)
        {
            <tr>exception.Message</tr>
        }
}

Blazor在多个过程中呈现,您所体验到的是绝对正常的。我的理解是,即使页面等待异步数据填充(复杂的数据库搜索等),也会加载大部分页面

有两种方法可以避免在async init上抛出null引用:

1.检查空值。别担心,组件将初始化所有内容,并在第二遍正确渲染

@if (Exceptions is not null){
    foreach (var exception in Exceptions)
        {
            <tr>exception.Message</tr>
        }
}

至于你为什么要找

你打电话:

protected override async void OnInitialized()
{
        var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
}
OnInitialized
OnInitializedAsync
的同步版本,应该只运行同步代码。您已将其转化为fire并忘记
async void
事件处理程序

它同步运行,直到它遇到一些真正的生成代码-
http.GetAsync
。在这一点上,它返回到组件
SetParametersAsync
。这将运行到完成。当
Exceptions=..
getrun
SetParametersAsync
完成时,组件已完成渲染并出错原因
异常
仍然为空

您需要在OnInitializedAsync()中运行代码。这会将任务返回到它可以等待的
SetParametersAsync
,并且只有当
OnInitializedAsync
通过返回已完成的任务完成时才会继续

    protected override async Task OnInitializedAsync()
    {
        var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
        Exceptions = JsonConvert.DeserializeObject<List<TestEventModel>>(await exceptionsResponse);
    }

当您在代码中调用
statehaschange
时,您需要询问原因?原因是有道理的,但通常是为了从先前的编码错误中恢复过来。

当您在寻找原因时

你打电话:

protected override async void OnInitialized()
{
        var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
}
OnInitialized
OnInitializedAsync
的同步版本,应该只运行同步代码。您已将其转化为fire并忘记
async void
事件处理程序

它同步运行,直到它遇到一些真正的生成代码-
http.GetAsync
。在这一点上,它返回到组件
SetParametersAsync
。这将运行到完成。当
Exceptions=..
getrun
SetParametersAsync
完成时,组件已完成渲染并出错原因
异常
仍然为空

您需要在OnInitializedAsync()中运行代码。这会将任务返回到它可以等待的
SetParametersAsync
,并且只有当
OnInitializedAsync
通过返回
@foreach (var item in Items)  
{

}
public List<string> Items { get; set; } = new();

protected override async Task OnInitializedAsync()
{
    Console.WriteLine("OnInitializedAsync start");
    await Task.Delay(100);
    Console.WriteLine("OnInitializedAsync done");
    Items = new List<string> { "aa", "bb", "cc", };        
}

protected override Task OnAfterRenderAsync(bool firstRender)
{
    Console.WriteLine($"OnAfterRenderAsync {firstRender}");
    return base.OnAfterRenderAsync(firstRender);
}