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

Blazor Server中数据不存在时如何返回带404状态码的页面?

Blazor Server 中针对数据不存在场景返回404状态码的实现方案

近年来这个问题被多次提及,但现有答案均存在以下问题之一:

  • 针对路由不存在场景(本文特指数据不存在的情况)
  • 需要使用IHttpContextAccessor(微软文档明确不建议此用法)
  • 重定向至未返回正确404响应头的资源(不利于SEO)
  • 在当前组件显示友好错误(不利于SEO,且需隐藏组件其他功能)
  • 涉及大量组件、页面及依赖注入(实现复杂,Web Forms或MVC中该需求实现相对简单)

ASP.NET Framework 中的简便实现

在ASP.NET Framework中,返回404状态码十分简便,可被IIS拦截或返回自定义页面,且可在控制/业务逻辑任意层级实现:

Web Forms

if (myThing == null) {
    var ctx = HttpContext.Current;
    ctx.Response.Clear();
    ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
    ctx.Response.StatusDescription = "No data was found against that URL.";
    ctx.Response.End();
}

ASP.NET Framework MVC

if (myThing == null) {
    ViewBag.ErrorMessage = "No data was found against that URL.";
    Response.StatusCode = (int)HttpStatusCode.NotFound;
    return View("~/Views/Error/NotFound.cshtml");
}

.NET Core Razor Pages

if (myThing == null) {
    return NotFound();
}

.NET Core Blazor Server 组件(@page)的等效实现?

当Blazor组件(.razor文件)配置为@page页面(而非嵌入在.cshtml文件中的组件)时,是否有等效的实现方式?

需说明的是:路由本身存在且正在处理请求,但对搜索引擎而言,带不同ID参数的相似URL会被索引为不同页面。

示例场景如下:

@page "/Product/{Id:int}"
@using Microsoft.EntityFrameworkCore

<h1>商品详情</h1>

@code {

    [Inject]
    IDbContextFactory<MyDbContext> _dbContextFactory { get; set; } = default!;

    [Parameter]
    public int? Id { get; set; }

    protected override async Task OnInitializedAsync()
    {
        using var context = _dbContextFactory.CreateDbContext();

        var thingToEdit = await context.MyEntities
                    .Where(e => e.EntityId == Id.Value)
                    .FirstOrDefaultAsync();

        if (thingToEdit == null)
        {
            // 跳转/显示404页面/消息,但必须设置HTTP状态码响应头
        }
        else
        {
            // 在该组件页面中显示商品详情
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:00:58