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

Blazor应用中网络断开致API调用失败时自定义提示的处理方法

Blazor断网场景下API调用失败的自定义提示处理方案

针对你遇到的断网时API调用异常无法被try-catch捕获、无法显示自定义提示的问题,可以从以下几个方面解决:

一、修正try-catch逻辑,覆盖网络相关异常类型

断网这类底层网络问题通常会抛出HttpRequestException或TaskCanceledException(请求中断/超时),如果你的try-catch只捕获了笼统的Exception,可能因为异步调用的问题没触发,或者没覆盖到特定异常类型。调整代码如下:

try
{
    var response = await _httpClient.GetFromJsonAsync<YourModel>("api/your-endpoint");
    
    // 处理API返回null的场景
    if (response == null)
    {
        ShowCustomMessage("网络连接异常,未获取到响应");
        return;
    }
    
    // 正常业务逻辑处理
}
catch (HttpRequestException)
{
    // 捕获断网、DNS失败等网络层面异常
    ShowCustomMessage("网络已断开,请检查连接后重试");
}
catch (TaskCanceledException)
{
    // 捕获请求超时或被中断的情况(断网常触发此异常)
    ShowCustomMessage("请求超时,请检查网络状态");
}
catch (Exception)
{
    // 其他异常兜底处理
    ShowCustomMessage("请求失败,请稍后重试");
}

⚠️ 必须确保API调用使用await,否则异步异常无法被当前try-catch块捕获。

二、用HttpClient拦截器全局统一处理

如果多个页面/组件都需要处理这类网络错误,可以自定义DelegatingHandler实现全局拦截,避免重复代码:

1. 自定义拦截器类

public class NetworkErrorHandler : DelegatingHandler
{
    private readonly IJSRuntime _jsRuntime;

    public NetworkErrorHandler(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        try
        {
            var response = await base.SendAsync(request, cancellationToken);
            
            // 处理响应无效或为空的情况
            if (response == null || !response.IsSuccessStatusCode)
            {
                await _jsRuntime.InvokeVoidAsync("showCustomToast", "网络请求异常,请检查连接");
            }
            
            return response;
        }
        catch (HttpRequestException)
        {
            await _jsRuntime.InvokeVoidAsync("showCustomToast", "网络已断开,请检查网络");
            throw; // 可选:抛出异常让上层继续处理,或返回空响应
        }
        catch (TaskCanceledException)
        {
            await _jsRuntime.InvokeVoidAsync("showCustomToast", "请求超时,请检查网络");
            throw;
        }
    }
}

2. 注册拦截器到DI容器

在Program.cs中添加以下代码:

builder.Services.AddScoped<NetworkErrorHandler>();
builder.Services.AddHttpClient("ApiClient")
    .AddHttpMessageHandler<NetworkErrorHandler>();

之后注入命名HttpClient(IHttpClientFactory)发起请求,即可全局拦截网络异常。

三、结合浏览器网络状态监听提前预警

除了API调用时的异常捕获,还可以利用浏览器原生的navigator.onLineAPI监听网络状态变化,提前给用户提示:

1. Blazor组件中添加监听逻辑

private bool _isOnline = true;
[Inject] private IJSRuntime JsRuntime { get; set; }

protected override async Task OnInitializedAsync()
{
    // 初始检查网络状态
    _isOnline = await JsRuntime.InvokeAsync<bool>("navigator.onLine");
    // 注册网络状态变化监听
    await JsRuntime.InvokeVoidAsync("registerNetworkListener", DotNetObjectReference.Create(this));
}

[JSInvokable]
public void UpdateNetworkStatus(bool isOnline)
{
    _isOnline = isOnline;
    if (!isOnline)
    {
        ShowCustomMessage("网络已断开,请检查连接");
    }
}

2. 在wwwroot/index.html中添加JS代码

<script>
    function registerNetworkListener(dotNetRef) {
        window.addEventListener('online', () => {
            dotNetRef.invokeMethodAsync('UpdateNetworkStatus', true);
        });
        window.addEventListener('offline', () => {
            dotNetRef.invokeMethodAsync('UpdateNetworkStatus', false);
        });
    }

    function showCustomToast(message) {
        // 替换成你的自定义弹窗组件调用,比如Blazored.Toast的Show方法
        alert(message); // 示例用原生alert,实际替换为你的组件逻辑
    }
</script>

四、关键注意事项

  • 确保HttpClient未禁用异常抛出:默认配置下,HttpClient在请求失败时会抛出异常,若手动设置了EnsureSuccessStatusCode(false),需自行判断响应状态。
  • 自定义提示组件推荐用成熟库(如Blazored.Toast),比原生alert体验更符合Blazor应用风格。
  • 若使用GetAsync而非GetFromJsonAsync,需额外检查HttpResponseMessage是否为null,并判断状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:55:14