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

Blazor应用按钮点击后数据未重载及状态更新异常排查

钥匙归还功能问题排查

业务流程

  • 用户点击按钮完成钥匙归还
  • 点击后页面重定向至当前页,按钮切换为“钥匙已归还”文本
  • 系统涉及两张表:
    • KeysList:存储所有可用钥匙,包含布尔类型状态字段IsReturned
    • KeyIssues:包含布尔类型状态字段IsReturned

现有问题

  1. KeyIssues表的状态并非总能成功更新,但KeysList表状态始终能正常更新
  2. 用户点击归还按钮后,仪表盘页面无法自动重载更新状态,必须切换到其他页面才能看到更新结果

相关代码

Dashboard页面代码

@*Key issues*@
<div class="card mb-4 shadow-lg p-3 mb-5 bg-white rounded">
    <div class="card-header text-center text-warning bg-white border-warning">
        <h4 class="">Laatste 5 sleuteluitgite</h4>
    </div>
    <div class="card-body">
        <div class="row">
            <div class="col">
                <h4 class="">Datum</h4>
            </div>
            <div class="col">
                <h4>Aan</h4>
            </div>
            <div class="col">
                <h4>Sleutel</h4>
            </div>
            <div class="col">
                <h4>Retour</h4>
            </div>
        </div>
    </div>

    @foreach (var item in keyIssues)
    {
        if (item == null)
        {
            <p>Loading..</p>
        }
        else
        {
            var SelectedId = @keysList.Where(m => m.Id.ToString() == item.KeyId).Select(m => m.Id).FirstOrDefault();
            <div class="row">
                <div class="col">
                    @item.DateAdded.ToShortDateString()
                </div>
                @if (item.IssuedTo != null)
                {
                    <div class="col">
                        @UserList.Where(m=>m.Id.ToString() == @item.IssuedTo).Select(m=>m.FirstName + " " + m.LastName).FirstOrDefault()
                    </div>
                    <div class="col">
                        @keysList.Where(m=>m.Id.ToString() == item.KeyId).Select(m=>m.KeyNumber + " " + m.KeyName).FirstOrDefault()
                    </div>
                }
                else
                {
                    <div class="col">
                        @item.FirstName @item.LastName
                    </div>
                    <div class="col">
                        @keysList.Where(m=>m.Id.ToString() == item.KeyId).Select(m=>m.KeyNumber + " " + m.KeyName).FirstOrDefault()
                    </div>
                }
              
                @if (item.IsReturned == false)
                {
                    <div class="col mb-2">
                        <button type="button" class="btn btn-outline-info" id="@item.Id" @onclick=" () => SetItemInactive(SelectedId)">Inleveren</button>
                    </div>
                }
                else
                {
                    <div class="col">
                        <p class="text-success">Retour</p>
                    </div>
                }
                <hr>
            </div>
        }
    }
</div>

async Task SetItemInactive(string id)
{
    var item = keysList.FirstOrDefault(m => m.Id == id);
    if (item != null)
    {
        if (KeyService != null)
        {
            await KeyService.SetItemInActive(item.Id);
        }
        StateHasChanged();
        if (item.IsReturned == true)
        {
            NavManager.NavigateTo("/");
        }
    }
}

Dashboard的IndexBase代码

using Microsoft.AspNetCore.Components;
using Univi.Client.Services.Interface;
using Univi.Server.Models;
using Univi.Shared;

namespace Univi.Client.Pages.Dashboard
{
    public partial class IndexBase : ComponentBase
    {
        [Inject]
        protected IReportService? ReportService { get; set; }
        [Inject] 
        protected IKeyService? KeyService { get; set; }
        [Inject]
        protected IKindofReportService? KindofReportService { get; set; }
        [Inject]
        protected IBuildingService? BuildingService { get; set; }
        [Inject]
        protected IHandoverService? HandoverService { get; set; }
        [Inject]
        protected IMalfunctionService? MalfunctionService { get; set; }
        [Inject]
        protected IUserService? UserService { get; set; }

        protected List<Report> ReportsList = new();
        protected List<KeyIssue> keyIssues = new();
        protected List<KeyList> keysList = new();
        protected List<Building> buildings = new();
        protected List<Kindofreport> kindofReports = new();
        protected List<Handover> handoverslist = new();
        protected List<Malfunction> malfunctionList = new();
        protected List<StatusCode> StatuscodeList = new();
        protected List<KindofMalfunction> KindofMalfunctionList = new();
        protected List<User> UserList = new();

        protected override async Task OnInitializedAsync()
        {
            if(HandoverService != null)
            {
                handoverslist = await HandoverService.GetHandovers();
            }

            if(ReportService != null)
            {
                ReportsList = await ReportService.GetLast5Reports();
            }
            if (KeyService != null)
            {
                keyIssues = await KeyService.GetKeyIssuesAsync();
                keysList = await KeyService.GetKeyListAsync();
            }
            if(BuildingService != null)
            {
                buildings = await BuildingService.GetBuildingsAsync();
            }
            if (KindofReportService != null)
            {
                kindofReports = await KindofReportService.GetKindsOfReportAsync();
            }
            if(MalfunctionService != null)
            {
                malfunctionList = await MalfunctionService.GetMalfunctionsAsync();
                StatuscodeList = await MalfunctionService.GetStatusCodesAsync();
            }
            if(UserService != null)
            {
                UserList = await UserService.GetUsersAsync();
            }
        }
    }
}

状态修改控制器代码

[HttpPost("inactive")]
public async Task<IActionResult> SetItemInactive([FromBody] string id)
{
    //Find the current key and set IsReturned to TRUE
    var item = await _context.KeysList.FindAsync(id);
   
    if (item != null)
    {
        var issue = _context.KeyIssues.Where(m => m.KeyId == id).FirstOrDefault();
        if (issue != null)
        {
             item.IsReturned = true;
             issue.IsReturned = true;
            if (issue.IsReturned == true && item.IsReturned == true)
            {
                _context.KeyIssues.Update(issue);
                _context.KeysList.Update(item);
                await _context.SaveChangesAsync();
                return Ok(item);
            }            
        }
    }
    return NoContent();
}

问题分析与修复方案

针对问题1:KeyIssues状态更新不稳定

  1. 控制器逻辑缺陷:
    • 同步查询FirstOrDefault()在异步方法中可能引发线程问题,需改为异步版本FirstOrDefaultAsync()
    • 冗余判断if (issue.IsReturned == true && item.IsReturned == true)完全无效,刚赋值为true无需再判断
    • 若同一钥匙存在多条KeyIssues记录,当前逻辑仅更新第一条,需批量处理所有关联记录

修复后的控制器代码:

[HttpPost("inactive")]
public async Task<IActionResult> SetItemInactive([FromBody] string id)
{
    var item = await _context.KeysList.FindAsync(id);
    if (item != null)
    {
        // 异步查询所有关联的KeyIssues记录
        var issues = await _context.KeyIssues.Where(m => m.KeyId == id).ToListAsync();
        if (issues.Any())
        {
            item.IsReturned = true;
            foreach(var issue in issues)
            {
                issue.IsReturned = true;
            }
            _context.KeysList.Update(item);
            _context.KeyIssues.UpdateRange(issues);
            await _context.SaveChangesAsync();
            return Ok(item);
        }
    }
    return NoContent();
}

针对问题2:仪表盘页面无法自动更新状态

  1. 前端数据未刷新:
    • 当前仅调用StateHasChanged(),但本地keyIssues和keysList未从服务器拉取最新数据,重新渲染用的还是旧数据
    • 导航到首页时未开启强制重载,Blazor默认会复用现有页面实例

修复后的前端SetItemInactive方法:

async Task SetItemInactive(string id)
{
    if (KeyService != null)
    {
        await KeyService.SetItemInActive(id);
        // 重新获取最新的钥匙和借出记录数据
        keyIssues = await KeyService.GetKeyIssuesAsync();
        keysList = await KeyService.GetKeyListAsync();
    }
    // 强制重载首页,确保页面完全刷新
    NavManager.NavigateTo("/", forceLoad: true);
}
  1. 额外优化:
    • 前端循环中SelectedId的查询完全冗余,item.KeyId本身就是钥匙ID,直接传递给SetItemInactive即可
    • 修改按钮点击事件:@onclick=" () => SetItemInactive(item.KeyId)"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:14:54