.NET MAUI调用Shell.GoToAsync("..")后退返根页、iOS触发空引用异常问题
问题根因
核心故障原因是混用了两套完全独立的导航栈体系:
- 你之前调用的
Navigation.PushAsync/Navigation.PushModalAsync属于传统NavigationPage维护的导航栈,和Shell导航体系的栈管理完全隔离,互相不感知对方栈内的页面。 Shell.Current.GoToAsync("..")只会操作Shell自身维护的路由导航栈,无法识别你通过传统Navigation接口压入的页面,因此执行后退时会直接回到Shell注册的根页面MainPage,不会按预期回退到上一级页面。- iOS端触发
System.NullReferenceException的原因是:iOS端你通过PushModalAsync压入的模态页不在Shell导航栈内,Shell执行后退路由时找不到对应页面的关联上下文,访问空对象就会抛出空引用异常。
修复方案
不要混用两套导航逻辑,统一全应用的导航栈实现,二选一即可:
方案1:沿用传统Navigation导航(改动最小,适配你现有代码)
将第三级页面的后退逻辑从Shell路由回退,替换为和压栈逻辑匹配的传统Navigation回退方法:
#if ANDROID // 对应Android端PushAsync压入的普通导航页,用PopAsync回退 await Navigation.PopAsync(true); #else // 对应iOS端PushModalAsync压入的模态页,用PopModalAsync回退 await Navigation.PopModalAsync(true); #endif
注意:采用该方案后,后续所有页面跳转、回退都要统一使用
Navigation的Push/Pop系列方法,不要再调用Shell.Current.GoToAsync执行导航操作,避免再次出现导航栈混乱。
方案2:全量迁移到Shell导航体系(长期维护更推荐)
- 将FriendsPage、FriendRatingsPage等所有业务页面注册到Shell路由表
- 替换所有原有
Navigation.PushXXX跳转逻辑,统一使用Shell.Current.GoToAsync指定路由完成跳转,不要跨体系调用导航方法 - 针对Android端模态页的已知兼容问题,可以通过Shell导航的页面打开参数单独配置Android端的页面展示模式,不需要单独编写平台分支使用PushModal接口
- 导航逻辑统一后,
Shell.Current.GoToAsync("..")就可以按照栈顺序正常回退,不会出现跳回根页、触发空引用的问题。
内容的提问来源于stack exchange,提问作者Steve Peschka
相关产品推荐
相关产品推荐

