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

编辑分类名称后UI显示陈旧数据(数据库数据正确)

Blazor Server分类编辑后UI显示错误问题解决

项目概述

我正在用Blazor Server/Web App开发学校的网店项目,已完成登录/注册页面,以及管理员可对分类执行增删改操作的概览页面。

问题描述

编辑分类时,系统不允许将分类名称修改为已存在的名称,后端逻辑已生效:提交重复名称时用户会收到错误提示,数据库中的分类名称也不会变更。但导航回分类概览页面时,UI却显示修改后的重复名称,刷新页面后该异常消失。

已尝试方案

我曾尝试以下操作,但均未解决问题:

  • 在OnInitializedAsync()中调用StateHasChanged()
  • 改用OnParametersSetAsync()加载数据
  • 监听NavigationManager.LocationChanged事件
  • 调用ResetCategory函数重置分类数据

问题根源

该问题由Blazor Server的组件状态缓存机制导致:分类概览页面的categories列表仅在组件初始化时加载一次,从编辑页面导航返回时,组件未重新获取最新的分类数据,仍使用之前缓存的对象(其中被修改名称的分类对象引用未更新,因此UI显示了未被数据库持久化的修改值)。

解决方案

方案1:订阅导航事件,返回页面时重新加载数据

修改分类概览页面代码,订阅NavigationManager.LocationChanged事件,每次导航到该页面时重新从数据库拉取分类数据:

@page "/categories"
@inject ICategoryService CategoryService
@inject NavigationManager NavigationManager
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@attribute [Authorize(Roles = "Administrator")]
@implements IDisposable

<PageTitle>Categorieën</PageTitle>
<h3>Categorieën</h3>

@if (categories.Count == 0)
{
    <p><em>Loading categories...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Naam</th>
                <th>Beschrijving (optioneel)</th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var category in categories)
            {
                <tr>
                    <td>@category.Name</td>
                    <td>@category.Description</td>
                    <td><button class="btn btn-primary" @onclick="@(() => EditCategory(category.Id))">Aanpassen</button></td>
                    <td><button class="btn btn-danger" @onclick="@(() => DeleteCategory(category.Id))">Verwijderen</button></td>
                </tr>
            }
        </tbody>
    </table>

    <button class="btn btn-primary" @onclick="AddCategory">Categorie toevoegen</button>
}

@code {
    List<Category> categories = new List<Category>();
    private IDisposable? _locationSubscription;

    protected override async Task OnInitializedAsync()
    {
        await LoadCategories();
        // 订阅导航变更事件
        _locationSubscription = NavigationManager.LocationChanged += OnLocationChanged;
    }

    private async void OnLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        // 判断是否导航回当前分类页面
        if (e.Location.Contains("/categories"))
        {
            await LoadCategories();
        }
    }

    // 封装加载分类的逻辑,便于复用
    private async Task LoadCategories()
    {
        categories = await CategoryService.GetAllCategoriesAsync();
        StateHasChanged();
    }

    void EditCategory(int? id)
    {
        NavigationManager.NavigateTo($"/edit-category/{id}");
    }

    async Task DeleteCategory(int id)
    {
        await CategoryService.DeleteCategoryAsync(id);
        await LoadCategories();
    }

    void AddCategory()
    {
        NavigationManager.NavigateTo("/edit-category");
    }

    // 释放订阅资源
    public void Dispose()
    {
        _locationSubscription?.Dispose();
    }
}

方案2:检查服务层是否存在缓存

若ICategoryService的实现中使用了内存缓存(如IMemoryCache),需确保GetAllCategoriesAsync方法每次都从数据库获取最新数据,而非返回缓存结果。例如移除服务层中对分类列表的缓存逻辑,或在编辑/删除操作后清空对应缓存。

方案3:强制整页刷新(不推荐)

虽然你已在编辑页面使用NavigationManager.NavigateTo("/categories", true)(第二个参数forceLoad设为true),该参数会强制浏览器整页刷新,若仍无效,需检查是否存在浏览器缓存或服务端输出缓存,可在响应头中添加禁用缓存的配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:14:52