Xamarin.Forms PushModalAsync后PopModalAsync报路由匹配歧义错误
.NET Shell "Ambiguous routes matched for" 问题解决方案
错误触发原因
关于路由匹配歧义
- 错误根源是同页面路由重复注册:手动调用
Routing.RegisterRoute("products/add", typeof(ProductAddPage))时,.NET Shell已经自动为视觉树中声明的ProductAddPage生成了带D_FAULT_前缀的默认路由,两个路由在当前导航上下文下解析出的路径完全一致,路由系统匹配到两个相同结果时就会抛出歧义异常。 - 报错信息中两个完全相同的匹配路径,就是手动注册路由与系统自动生成路由的解析结果完全重合的直接表现。
关于模态导航弹出失败
PushModalAsync走独立模态导航栈,执行时不会触发Shell全局路由全链路校验,因此扫码页可以正常弹出,扫码结果也能正常赋值。- 调用
PopModalAsync时,Shell会同步校验整个导航栈的路由合法性,扫描到重复注册的路由条目时直接抛出异常,导致弹出流程中断。
修复步骤
- 清理重复路由注册:删除
Routing.RegisterRoute("products/add", typeof(ProductAddPage))这行代码。如果ProductAddPage未在Shell.xaml中声明、必须手动注册,更换注册路径为非嵌套格式,比如Routing.RegisterRoute("productAdd", typeof(ProductAddPage)),避免与系统自动生成的层级路由冲突。 - 优化扫码页导航逻辑,增加重复调用拦截,避免回调多次触发导航操作:
private bool _isNavigating = false; private async void OpenBarcodeReader() { _isNavigating = false; var scanPage = new ZXingScannerPage(); scanPage.OnScanResult += (result) => { if (_isNavigating) return; _isNavigating = true; scanPage.IsScanning = false; MainThread.BeginInvokeOnMainThread(async () => { try { if (Navigation.ModalStack.LastOrDefault() == scanPage) { await Navigation.PopModalAsync(); } Product.EAN = result.Text; } catch (Exception ex) { Console.WriteLine($"导航异常: {ex.Message}"); } }); }; await Navigation.PushModalAsync(scanPage); }
- 清理项目
bin、obj目录后重新生成解决方案,清除旧的路由注册缓存。
内容的提问来源于stack exchange,提问作者DamianS
相关产品推荐
相关产品推荐

