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

如何在Blazor WASM(ASP.NET Core托管)模板中正确显示错误页?

在Blazor托管模板中正常显示服务端错误页的方案

问题根源

Blazor WASM客户端是单页应用,服务端通过app.UseExceptionHandler("/Error");返回的HTML错误页会被客户端路由系统忽略,无法被正常渲染,只能在浏览器检查器中看到原始响应内容。

两种可行解决方案

方案一:服务端返回结构化错误,客户端处理显示

适合API请求场景,让服务端返回JSON格式的错误信息,客户端捕获后显示自定义错误UI:

  1. 修改服务端异常处理逻辑
    替换原有的app.UseExceptionHandler("/Error");,改为返回JSON错误:
    app.UseExceptionHandler(errorApp =>
    {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = "application/json";
            
            var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
            var errorDetails = new 
            { 
                Message = "服务器运行时发生异常", 
                ExceptionMessage = exceptionFeature?.Error.Message,
                RequestPath = exceptionFeature?.Path
            };
            
            await context.Response.WriteAsJsonAsync(errorDetails);
        });
    });
    
  2. 客户端全局错误处理
    • 在App.razor中用ErrorBoundary组件包裹路由区域,统一处理组件级错误:
      <ErrorBoundary>
          <Router AppAssembly="@typeof(App).Assembly">
              <Found Context="routeData">
                  <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
              </Found>
              <NotFound>
                  <LayoutView Layout="@typeof(MainLayout)">
                      <p>请求的页面不存在</p>
                  </LayoutView>
              </NotFound>
          </Router>
          <ChildContent>
              <LayoutView Layout="@typeof(MainLayout)">
                  <h2>抱歉,发生了未知错误</h2>
                  <p>@context?.Exception.Message</p>
              </LayoutView>
          </ChildContent>
      </ErrorBoundary>
      
    • 对于API调用,在客户端的HTTP服务中捕获异常,显示对应提示:
      public async Task<T> GetAsync<T>(string url)
      {
          try
          {
              var response = await _httpClient.GetFromJsonAsync<T>(url);
              return response;
          }
          catch (HttpRequestException ex)
          {
              // 可在此处弹出错误提示或触发全局错误状态
              Console.WriteLine($"API请求错误: {ex.Message}");
              throw;
          }
      }
      

方案二:复用服务端错误页内容,在客户端渲染

如果需要保留原Razor错误页的内容,可以将错误页改为共享组件,让客户端和服务端都能使用:

  1. 将服务端Error页转为共享组件
    在Shared项目中创建ErrorComponent.razor,迁移原服务端Error.cshtml的内容:
    <h1>服务器错误</h1>
    <p>请求处理时出现问题,请稍后重试。</p>
    @if (ErrorDetails != null)
    {
        <p>错误详情: @ErrorDetails.Message</p>
    }
    
    @code {
        [Parameter]
        public object ErrorDetails { get; set; }
    }
    
  2. 调整服务端异常处理逻辑
    判断请求是否来自Blazor客户端,重定向到客户端的错误路由:
    app.UseExceptionHandler(errorApp =>
    {
        errorApp.Run(async context =>
        {
            // 通过请求头判断是否为Blazor客户端请求
            var isBlazorClient = context.Request.Headers["Accept"].ToString().Contains("text/html") &&
                                !context.Request.Path.StartsWithSegments("/api");
            
            if (isBlazorClient)
            {
                // 重定向到客户端错误路由
                context.Response.Redirect("/client-error");
            }
            else
            {
                // 非Blazor请求返回原HTML错误页
                var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
                await context.Response.WriteAsync($"<html><body><h1>服务器错误</h1><p>{exceptionFeature?.Error.Message}</p></body></html>");
            }
        });
    });
    
  3. 客户端添加错误路由
    在App.razor的Router中添加全局错误捕获:
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>请求的页面不存在</p>
            </LayoutView>
        </NotFound>
        <!-- 全局错误捕获 -->
        <Error>
            <LayoutView Layout="@typeof(MainLayout)">
                <Shared.ErrorComponent ErrorDetails="@context.Exception" />
            </LayoutView>
        </Error>
    </Router>
    
    同时在客户端Routes.razor中添加/client-error路由:
    <Route Route="/client-error">
        <Shared.ErrorComponent />
    </Route>
    

注意事项

  • 区分API请求和页面请求:API请求优先返回JSON错误,页面请求可返回客户端可渲染的错误组件
  • 如果使用预渲染模式,服务端的错误可直接在预渲染阶段显示,无需额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:45:13