在Blazor中使用App.razor的ErrorBoundary时调用Recover()的位置 &



我做什么

我在App.brazor中使用ErrorBoundary在发生异常时在自定义布局中显示错误。
我使用以下代码:

App.razor

<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
// use ErrorBoundary in App.razor
<ErrorBoundary>
<ChildContent>
...
</ChildContent>
<ErrorContent>
// using custom layout
<LayoutView Layout="typeof(ErrorLayout)">
<Error500 Exception="@context" />
</LayoutView>
</ErrorContent>
</ErrorBoundary>
</Found>
...
</Router>

ErrorLayout.razor

@inherits LayoutComponentBase
<PageTitle>BlazorApp2</PageTitle>
@Body

Error500.razor

<PageTitle>Server Error</PageTitle>
<h1>Server Error</h1>
<pre>@Exception?.ToString()</pre>
@code {
[Parameter]
public Exception? Exception { get; set; }
}

预期行为预期行为。(代码示例BlazorApp1)

  1. Counter链接点击->/counter
  2. Home链接点击->对/
  3. 的影响
  4. Error按钮点击->显示错误。
  5. 浏览器返回->返回/counter并显示页面精细🆗

我的代码行为。(代码示例BlazorApp2)

  1. Counter链接点击->/counter
  2. Home链接点击->/
  3. Error按钮点击->显示错误。
  4. 浏览器返回->修改到/counter,但仍然显示错误信息,因为异常尚未清除🆖

问题我想在发生错误后返回浏览器时显示前一个屏幕。
要做到这一点,我想调用ErrorBoundary.Recover()来清除异常,但我不知道在哪里调用它。

通常,当在布局中放置ErrorBoundary时,会使用以下语句:

MainLayout.razor

// https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/handle-errors?view=aspnetcore-6.0#error-boundaries
...
<ErrorBoundary @ref="errorBoundary">
@Body
</ErrorBoundary>
...
@code {
private ErrorBoundary? errorBoundary;
protected override void OnParametersSet()
{
errorBoundary?.Recover();
}
}

我对App.razor做了类似的操作,如下所示。

App.razor

<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<ErrorBoundary @ref="errorBoundary">
<ChildContent>
...
</ChildContent>
<ErrorContent>
<CascadingValue Value="errorBoundary">
<LayoutView Layout="typeof(ErrorLayout)">
<Error500 Exception="@context" />
</LayoutView>
</CascadingValue>
</ErrorContent>
</ErrorBoundary>
</Found>
...
</Router>
@code {
private ErrorBoundary? errorBoundary;
protected override void OnParametersSet()
{
// Not called when navigation or browser back
System.Diagnostics.Debug.WriteLine("**** OnParametersSet App ****");
//errorBoundary?.Recover();
}
}

但是,App.razor的OnParametersSet()不会在浏览器返回或导航时调用。

如果我在App.razor中放置了一个ErrorBoundary,我应该在哪里调用ErrorBoundary. recover ()?

其他我尝试过的东西1

如果执行以下操作,异常信息被清除,错误屏幕将无法显示。

  • 使ErrorBoundary成为错误显示组件的参数
  • 错误显示组件的OnParametersSet()中的Call Recovery()

App.razor

<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<ErrorBoundary @ref="errorBoundary">
<ChildContent>
...
</ChildContent>
<ErrorContent>
<LayoutView Layout="typeof(ErrorLayout)">
<Error500 Exception="@context" ErrorBoundary="errorBoundary"/>
</LayoutView>
</ErrorContent>
</ErrorBoundary>
</Found>
...
</Router>
@code {
private ErrorBoundary? errorBoundary;
}

Error500.razor

<PageTitle>Server Error</PageTitle>
<h1>Server Error</h1>
<pre>@Exception?.ToString()</pre>
@code {
[Parameter]
public Exception? Exception { get; set; }
[Parameter]
public ErrorBoundary? ErrorBoundary { get; set; }
protected override void OnParametersSet()
{
ErrorBoundary?.Recover();
}
}

我尝试了2

我尝试使用CascadingValue将ErrorBoundary传递给ErrorLayout,并在ErrorLayout. onparameterset()中调用Recover()。
无法显示错误屏幕,因为异常信息已被清除

App.razor

<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<ErrorBoundary @ref="errorBoundary">
<ChildContent>
...
</ChildContent>
<ErrorContent>
<CascadingValue Value="errorBoundary">
<LayoutView Layout="typeof(ErrorLayout)">
<Error500 Exception="@context" />
</LayoutView>
</CascadingValue>
</ErrorContent>
</ErrorBoundary>
</Found>
<NotFound>
...
</NotFound>
</Router>
@code {
private ErrorBoundary? errorBoundary;
}

ErrorLayout.razor

@inherits LayoutComponentBase
<PageTitle>BlazorApp2</PageTitle>
@Body
@code {
[CascadingParameter]
public ErrorBoundary? ErrorBoundary { get; set; }
protected override void OnParametersSet()
{
ErrorBoundary?.Recover();
}
}
<标题>

代码示例用于检查的代码放在下面。https://github.com/usausa/question-blazor-errorhandle

我想做的完整的代码样本。https://github.com/usausa/Example-Net-Blazor/tree/main/ErrorHandleExample

From your Expected Behavior,当您点击Recovery按钮时,您想要返回到/counter页面,并使用OnParametersSet()方法来恢复异常。由于EventCallback不能在父组件中调用OnParametersSet()方法,您可以尝试直接导航到/counter,然后项目将调用OnParameterSet()方法来恢复异常。

Error500.razor

@inject NavigationManager _navigationManager
<PageTitle>Server Error</PageTitle>
<h1>Server Error</h1>
<pre>@Exception?.ToString()</pre>
<button @onclick="ErrorRecover">Recovery</button>

@code {
[Parameter]
public Exception? Exception { get; set; }

[Parameter]
public EventCallback<MouseEventArgs> RecoverRequest { get; set; }
private void ErrorRecover()
{
_navigationManager.NavigateTo("/counter");
}
}

MainLayout

@inherits LayoutComponentBase
<PageTitle>BlazorApp2</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
<ErrorBoundary @ref="_errorBoundary">
<ChildContent >
@Body
</ChildContent>
<ErrorContent >
<LayoutView Layout="typeof(ErrorLayout)">
<Error500 Exception="@context" />
</LayoutView>
</ErrorContent>
</ErrorBoundary>
</article>
</main>
</div>
@code 
{
private ErrorBoundary? _errorBoundary;

protected override void OnParametersSet()
{
_errorBoundary?.Recover();
}
}

最新更新