You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建C# Blazor(Server-side)全局异常处理器?(非WebAssembly)

Blazor Server 全局异常处理器实现(含文本日志写入)

Blazor Server的异常场景分为组件交互/渲染异常、SignalR电路连接异常、初始HTTP请求异常三类,以下是针对性的全局处理方案,同时实现异常日志写入文本文件。

1. 实现自定义文件日志服务

先创建一个负责写入异常日志到文本文件的服务:

public interface IFileLogger
{
    void LogException(Exception ex, string context);
}

public class FileLogger : IFileLogger
{
    private readonly string _logDir;

    public FileLogger()
    {
        // 日志存储目录,可根据需求调整
        _logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "BlazorLogs");
        Directory.CreateDirectory(_logDir);
    }

    public void LogException(Exception ex, string context)
    {
        var logFileName = $"Error_{DateTime.Now:yyyyMMdd}.txt";
        var fullPath = Path.Combine(_logDir, logFileName);
        
        var logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 场景: {context}\n异常详情:\n{ex.ToString()}\n\n";
        File.AppendAllText(fullPath, logContent);
    }
}

在Program.cs中注册这个服务:

builder.Services.AddSingleton<IFileLogger, FileLogger>();

2. 捕获组件全局异常

通过自定义ErrorBoundary组件,捕获所有组件渲染、交互时的未处理异常:

创建GlobalErrorBoundary.razor组件:

@inherits ErrorBoundary
@inject IFileLogger FileLogger

@ChildContent

@code {
    protected override Task OnErrorAsync(Exception exception)
    {
        // 记录组件异常日志
        FileLogger.LogException(exception, "组件渲染/交互异常");
        
        // 自定义错误提示(可根据需求修改)
        ErrorContent = builder =>
        {
            builder.AddMarkupContent(0, @"
                <div class=""alert alert-danger"">
                    <h4>出错了</h4>
                    <p>系统遇到未预期的错误,请稍后重试。</p>
                </div>");
        };

        return base.OnErrorAsync(exception);
    }
}

修改App.razor,用自定义错误边界包裹整个路由:

<GlobalErrorBoundary>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>未找到页面</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">抱歉,该地址不存在。</p>
            </LayoutView>
        </NotFound>
    </Router>
</GlobalErrorBoundary>

3. 处理SignalR电路/连接异常

Blazor Server基于SignalR通信,电路连接异常可通过自定义CircuitHandler捕获:

public class GlobalCircuitHandler : CircuitHandler
{
    private readonly IFileLogger _fileLogger;

    public GlobalCircuitHandler(IFileLogger fileLogger)
    {
        _fileLogger = fileLogger;
    }

    // 捕获连接断开异常
    public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        _fileLogger.LogException(new Exception("SignalR连接已断开"), "电路连接异常");
        return base.OnConnectionDownAsync(circuit, cancellationToken);
    }

    // 捕获电路关闭异常
    public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        _fileLogger.LogException(new Exception($"电路[{circuit.Id}]已关闭"), "电路生命周期异常");
        return base.OnCircuitClosedAsync(circuit, cancellationToken);
    }
}

在Program.cs中注册:

builder.Services.AddScoped<CircuitHandler, GlobalCircuitHandler>();

4. 捕获初始HTTP请求异常

Blazor Server首次加载是HTTP请求,这类异常可通过ASP.NET全局异常中间件处理:

在Program.cs中,app.UseRouting()之后、app.MapBlazorHub()之前添加:

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionFeature?.Error != null)
        {
            var fileLogger = context.RequestServices.GetRequiredService<IFileLogger>();
            fileLogger.LogException(exceptionFeature.Error, "初始HTTP请求异常");
            
            context.Response.StatusCode = 500;
            await context.Response.WriteAsync("系统初始化出错,请刷新页面重试。");
        }
    });
});

注意事项

  • 组件内的异步操作必须正确await,否则未捕获的异步异常可能无法被ErrorBoundary捕获,建议在组件内对关键异步代码添加try-catch补充处理。
  • 日志文件路径可根据部署环境调整(如生产环境可配置到特定日志目录)。

内容的提问来源于stack exchange,提问作者Jck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:07:15