.NET 8 Blazor Server向导式导航方案选型与实现咨询
Blazor Server 导航方案选型疑问(.NET 8)
我基于.NET 8开发Blazor Server应用,正在探索应用内的导航方案,目前已实现两种方式:
- 扩展
NavigationManager,配合修改MainLayout的@Body来传递额外数据 - 把
Index.razor作为DynamicComponent容器,通过切换组件类型实现页面切换
我的核心疑问是:面向数千用户的公开应用,哪种方案更适配业务场景且更直观?目前阻碍我选NavigationManager方案的原因是没法便捷地给目标页面传输入参数。
需求明确
- 支持携带不同参数导航到对应路由
- 页面间保存当前步骤
- 根据页面执行结果(成功/错误)决定跳转目标(比如成功进下一页,错误跳错误页)
- 不需要步骤书签或可篡改URL跳转步骤,需将最后执行的步骤(向导进度)持久化到数据库,支持中断后恢复流程
- 步骤逻辑规则:
- 步骤:代表向导中的独立任务
- 每个步骤仅知晓自身操作,能判定操作成功/失败,但不决定下一步
- 步骤路由:中央组件,负责接收步骤名称、执行结果及可选参数,根据预设逻辑确定下一步骤,并返回下一步骤名称及需传递的参数
- 步骤数据:用于步骤间传递数据的对象(类似MVC TempData),可由步骤路由或独立服务管理
方案一:扩展NavigationManager实现
实现代码
public class NavigationProvider { private readonly NavigationManager _navigationManager; public NavigationProvider(NavigationManager navigationManager) { _navigationManager = navigationManager; } public StepEnum CurrentStep { get; private set; } = Step.Undefined; public Dictionary<string, object> PassedParameters { get; private set; } public void NavigateTo(OutcomeEnum outcome, Dictionary<string, object> passedParameters) { this.PassedParameters = passedParameters; StepEnum nextStep = ChooseNextStep(outcome); this.Navigate(nextStep); } private StepEnum ChooseNextStep(OutcomeEnum outcome) { StepEnum nextStep = StepEnum.Undefined; switch (CurrentStep) { case StepEnum.Login: nextStep = StepEnum.Dashboard; break; case StepEnum.Dashboard: nextStep = StepEnum.ExecuteAction; break; case StepEnum.ExecuteAction: nextStep = StepEnum.EndOfUserAction; break; default: nextStep = StepEnum.ErrorPage; break; } return nextStep; } private void Navigate(StepEnum nextStep) { _navigationManager.NavigateTo(nextStep.ToString()); } } public enum OutcomeEnum { ErrorInBusinessLogic, SuccessfulRedirect } public enum StepEnum { Login, Dashboard, ExecuteAction, EndOfActionExecute, ErrorPage }
疑问点
- 这是Blazor Server应用的标准导航方式吗?
- 如何为每个页面创建带输入参数的视图模型并在导航时传递?
方案二:DynamicComponent容器实现
核心思路
在Index.razor中用DynamicComponent作为容器,无需使用NavigationManager,通过切换组件类型实现页面切换。
Index.razor 代码
<DynamicComponent Type="ComponentType" Parameters="ComponentParameters" />
Index.razor.cs 代码
public Type ComponentType { get; set; } = typeof(Login); public Dictionary<string, object> ComponentParameters { get; set; } protected override void OnInitialized() { this.ComponentParameters = new Dictionary<string, object> { { "NavigateRequest", new Action<NavArgs>(HandleNavigateRequest) } }; base.OnInitialized(); } public void HandleNavigateRequest(NavArgs args) { this.ComponentType = args.CurrentStep switch { StepEnum.Registration => typeof(Dashboard), StepEnum.Dashboard=> typeof(ExecuteAction), StepEnum.ExecuteAction=> typeof(EndOfActionExecute), _ => this.ComponentType // 默认保持当前组件类型 }; }
子页面触发导航代码
[Parameter] public Action<NavArgsType> NavigateRequest { get; set; } public void RequestNavigate() { var args = new NavArgs() { CurrentStep = StepEnum.Login, }; this.NavigateRequest.Invoke(args); }
核心疑问
是否可通过改造标准NavigationManager实现该设计,还是需要采用DynamicComponent等其他方案?
内容的提问来源于stack exchange,提问作者dlght
相关产品推荐
相关产品推荐

