【问题标题】:Get the current exception in blazor Error Boundary获取 blazor Error Boundary 中的当前异常
【发布时间】:2023-02-01 09:28:59
【问题描述】:

我有一个在我的应用程序的特定上下文中生成的异常。 我希望能够收集它,将它发送到记录器并恢复以前的状态。

问题是无法访问此错误绑定异常,因为它的当前异常属性是受保护的。

解决方案是什么?

【问题讨论】:

    标签: c# exception logging blazor .net-6.0


    【解决方案1】:

    我希望能够收集它并将其发送到记录器并恢复以前的状态。

    创建一个组件如下(Error.razor):

    @using Microsoft.Extensions.Logging
    @inject ILogger<Error> Logger
    @inject IJSRuntime jsRuntime
    
    <CascadingValue Value="this">
    @ChildContent
    </CascadingValue>    
    @code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    
    public void ProcessError(Exception ex)
    {
        Logger.LogError("Error:ProcessError - Type: {Type} Message: {Message}",
            ex.GetType(), ex.Message);
        jsRuntime.ToastrError("An Error has occured!"); 
        //StateHasChanged();       
    }
    

    }

    Error 组件可以使用 Blazor 内置记录器记录错误,并通过 ProcessError 方法使用 Toastr 显示 JavaScript 错误消息。显然,其他记录器如 Serilog、Elmah 甚至其他自定义记录器都可以用于登录此方法。

    StateHasChanged 将在错误处理方法想要直接干预发生异常的组件的用户界面渲染时使用。例如,当我们想要在错误发生后更改页面的呈现元素时(更改按钮的颜色或标签或文本框的字体颜色或...)。

    现在,我们编辑 App.razor 组件如下:

    <Error>
        <Router ...>
            ...
        </Router>
    </Error>
    

    实际上,我们通过自己的自定义组件(Error.razor)将 Router 组件封装起来,以便将 Error 组件级联到任何将 Error 视为[CascadingParameter] 的程序组件。

    现在,在其他组件中按如下方式处理错误就足够了:

    @code {
        [CascadingParameter]
        public Error? Error { get; set; }
    
        private void CreatePost()
        {
            try
            {
               throw new InvalidOperationException("a message!");
            }
            catch (Exception ex)
            {
                Error?.ProcessError(ex);
            }
        }
    }
    

    如您所见,Error 组件定义为 CascadingParameter,在 try catch 块中,调用 Error 组件的 ProcessError 方法并将发出的异常发送给它。在我的示例中,Error 组件只有一种错误处理方法。显然,这个组件可以有几个其他的自定义错误处理方法用于不同的目的。

    要将日志保存在服务器上的文本文件中,您可以使用 Serilog,其方法在here 中有说明。您还可以使用 custom log provider 将日志保存到数据库中。

    【讨论】:

      【解决方案2】:

      CurrentException 属性是受保护的,不是私有的,因此您可以定义此类:

      public class MyErrorBoundary : ErrorBoundary
      {
          public new Exception? CurrentException => base.CurrentException;
      }
      

      然后在所有代码中将 ErrorBoundary 替换为 MyErrorBoundary。瞧。

      【讨论】:

        猜你喜欢
        • 2022-12-02
        • 2021-05-04
        • 2018-10-10
        • 2014-01-14
        • 2013-07-31
        • 2020-11-16
        • 2020-06-01
        • 2012-08-16
        相关资源
        最近更新 更多