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

Blazor Server单页多路由绑定不同ViewModel总选中第二个的问题

问题原因

Blazor 的 @inject 指令属于编译期静态注入逻辑,不会受运行时 @if 判断块的控制。你写在两个判断块里的注入声明都会在页面编译阶段被处理,同名的 viewmodel 变量会被后声明的注入值覆盖,因此无论访问哪个路由,最终拿到的都是第二个ViewModel实例。

解决方案

推荐通过IServiceProvider在运行时动态获取对应ViewModel实例,操作步骤如下:

  1. 首先为两个ViewModel定义公共接口(可选但推荐,保证类型安全,避免后续绑定时的类型转换问题)
public interface ICanSimViewModel
{
    // 把两个ViewModel共有的属性、方法声明在这里
}

// 两个ViewModel分别实现该接口
public class CanSimStaicViewModell : ICanSimViewModel
{
    // 原有逻辑
}

public class CanSimDynamicViewModdels : ICanSimViewModel
{
    // 原有逻辑
}
  1. 修改页面代码,移除判断块内的静态@inject,改为运行时从DI容器获取实例:
@page "/canSimStatic"
@page "/CanSimDynamic"
@using System.Diagnostics;
@using edge_cantraficSimulator.Data
@using edge_cantraficSimulator.ViewModels
@using System.Threading;
@using System.IO;
@using Microsoft.AspNetCore.Mvc.Rendering;
@inject NavigationManager NavigationManager
@inject IServiceProvider ServiceProvider
@implements IAsyncDisposable

@* 后续页面视图正常绑定viewmodel的属性即可 *@
<div>@viewmodel.SomeProperty</div>

@code {
    private ICanSimViewModel viewmodel;

    protected override void OnInitialized()
    {
        if (NavigationManager.Uri.Contains("canSimStatic", StringComparison.OrdinalIgnoreCase))
        {
            viewmodel = ServiceProvider.GetRequiredService<CanSimStaicViewModell>();
        }
        else if (NavigationManager.Uri.Contains("CanSimDynamic", StringComparison.OrdinalIgnoreCase))
        {
            viewmodel = ServiceProvider.GetRequiredService<CanSimDynamicViewModdels>();
        }
        base.OnInitialized();
    }

    // 如果你的ViewModel实现了IDisposable/IAsyncDisposable,需要手动释放
    public async ValueTask DisposeAsync()
    {
        if (viewmodel is IAsyncDisposable asyncDisposable)
        {
            await asyncDisposable.DisposeAsync();
        }
        else if (viewmodel is IDisposable disposable)
        {
            disposable.Dispose();
        }
    }
}

如果不想做接口抽象,也可以把viewmodel声明为dynamic类型,但会缺失编译期类型检查,不推荐。

可选替代方案

你也可以拆分两个独立页面分别对应两个路由,两个页面共用同一个布局组件做视图渲染,每个页面单独注入对应的ViewModel,逻辑更符合Blazor的常规设计,不需要额外处理动态注入的释放问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:27:03