我做什么
我在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)
Counter
链接点击->/counter
Home
链接点击->对/
的影响Error
按钮点击->显示错误。- 浏览器返回->返回
/counter
并显示页面精细🆗
我的代码行为。(代码示例BlazorApp2)
Counter
链接点击->/counter
Home
链接点击->/
Error
按钮点击->显示错误。- 浏览器返回->修改到
/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();
}
}