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

Blazor Server应用中Scoped服务更新共享变量后Razor页面未同步显示的问题排查

Blazor Server应用中Scoped服务更新共享变量后Razor页面未同步显示的问题排查

嘿,我来帮你搞定这个问题!你遇到的是Blazor Server中非常典型的「状态更新后组件未同步」的问题,主要有几个核心的错误需要修正,咱们一步步来:

1. TagService缺少属性变更通知机制

Blazor组件不会自动监听普通POCO类的属性变化——只有当组件自身状态变更,或者收到明确的属性变更通知时,才会重新渲染页面。你的TagService只是简单的自动属性,修改值后组件根本不知道要刷新。

修正方案:让TagService实现INotifyPropertyChanged接口
这个接口是.NET中标准的属性变更通知机制,当属性值变化时触发事件,组件订阅后就能自动刷新。

修改后的TagService代码:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WebApplication7.Services
{
    public class TagService : INotifyPropertyChanged
    {
        private int _tag1 = 0;
        private int _tag2 = 0;
        private int _tag3 = 0;

        public int Tag1
        {
            get => _tag1;
            set
            {
                if (_tag1 != value)
                {
                    _tag1 = value;
                    OnPropertyChanged();
                }
            }
        }

        public int Tag2
        {
            get => _tag2;
            set
            {
                if (_tag2 != value)
                {
                    _tag2 = value;
                    OnPropertyChanged();
                }
            }
        }

        public int Tag3
        {
            get => _tag3;
            set
            {
                if (_tag3 != value)
                {
                    _tag3 = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

另外注意:你原来的代码里重复定义了Tag2属性(应该是Tag3),这个笔误会导致逻辑错误,已经在上面修正了。

2. SetTags服务的注入方式错误

[Inject]属性只在Blazor组件(Razor页面/组件)中生效,服务类之间的依赖注入必须用构造函数注入——你原来的SetTags里的TagService其实是null,调用Set_Values()的时候根本没修改到真实的TagService实例!

修正方案:用构造函数注入TagService
修改后的SetTags代码:

namespace WebApplication7.Services
{
    public class SetTags
    {
        private readonly TagService _tagService;

        // 通过构造函数注入TagService,这是服务间依赖注入的正确方式
        public SetTags(TagService tagService)
        {
            _tagService = tagService;
        }

        public void Set_Values()
        {
            _tagService.Tag1 = 32;
            _tagService.Tag2 = 24;
            _tagService.Tag3 = 20; // 修正原来的重复Tag2问题
            // 其他标签的设置逻辑
        }
    }
}

3. Razor页面需要订阅属性变更事件

现在TagService能发出变更通知了,还需要让Razor页面订阅这个事件,这样属性变化时组件才会重新渲染。

修改后的Razor页面代码:

@page "/razor_page1"
@using WebApplication7.Services
@inject TagService TagService
@inject SetTags SetTags
@implements IDisposable <!-- 实现IDisposable用于取消订阅事件,避免内存泄漏 -->

<td>
    <button class="button_1" @onclick="func_button">更新标签</button>
</td>
<div>
    <p>Tag1: @TagService.Tag1</p>
    <p>Tag2: @TagService.Tag2</p>
    <p>Tag3: @TagService.Tag3</p>
</div>

@code {
    protected override void OnInitialized()
    {
        // 订阅TagService的属性变更事件,触发组件重新渲染
        TagService.PropertyChanged += (sender, e) => StateHasChanged();
    }

    public void func_button()
    {
        SetTags.Set_Values();
        // 如果没有订阅事件,这里可以手动调用StateHasChanged(),但推荐用事件订阅的方式
        // StateHasChanged();
    }

    public void Dispose()
    {
        // 页面销毁时取消订阅,避免内存泄漏
        TagService.PropertyChanged -= (sender, e) => StateHasChanged();
    }
}

最后验证你的Startup配置

你的Startup.cs里的服务注册是正确的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ConnectService>();
    services.AddScoped<TagService>();
    services.AddScoped<SetTags>();
}

Scoped服务在Blazor Server中是每个用户会话一个实例,所以多个页面会共享同一个TagService实例,修改后所有页面都会同步显示最新值。

备注:内容来源于stack exchange,提问作者Mdarende

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 13:34:36