.NET MAUI导航传参为空问题求助:SectionId接收始终为0
问题分析与解决方案
核心问题是导航参数传递时机和ViewModel初始化顺序不匹配:
- 你通过
Create方法创建ViewModel时,立刻调用了Initialize->GetuppliersList,但此时Shell还未完成SectionId参数的传递,导致SectionId始终是默认值0。 - Shell的
QueryProperty赋值操作,是在ViewModel被设置为页面BindingContext之后才执行的,这就造成API调用时用了错误的ID。
修复步骤
1. 修改ViewModel的参数触发逻辑
把数据加载逻辑绑定到SectionId的属性变更事件上,确保参数传递完成后再调用API:
[QueryProperty(nameof(SectionId),"SectionId")] public partial class SelectSupplierPageViewModel : ObservableObject { int sectionId; public int SectionId { get => sectionId; set { // 用SetProperty替代手动调用OnPropertyChanged,符合ObservableObject规范 if (SetProperty(ref sectionId, value)) { // 参数赋值完成后自动触发数据加载 _ = GetuppliersList(); } } } private ObservableCollection<Supplier> _suppliers = new(); public ObservableCollection<Supplier> Suppliers { get => _suppliers; set => SetProperty(ref _suppliers, value); } public SelectSupplierPageViewModel() { } public async Task GetuppliersList() { // 避免初始值0触发无效API请求 if (SectionId == 0) return; var supplierUrl = $"https://localhost:7282/api/SectionSupliers/GetSuppliersInSection/{SectionId}"; using (var client = new HttpClient()) { try { var apiResponse = await client.GetAsync(supplierUrl); // 主动抛出HTTP错误,便于调试排查问题 apiResponse.EnsureSuccessStatusCode(); var content = await apiResponse.Content.ReadAsStringAsync(); var supplierList = JsonConvert.DeserializeObject<List<Supplier>>(content); Suppliers.Clear(); if (supplierList?.Count > 0) { foreach (var supplier in supplierList) { Suppliers.Add(supplier); } } } catch (Exception ex) { // 可添加错误提示逻辑,比如弹窗通知用户 Console.WriteLine($"加载供应商失败: {ex.Message}"); } } } }
2. 简化页面的BindingContext设置
无需在OnAppearing中异步创建ViewModel,直接在构造函数中初始化,让Shell自动处理参数传递:
public SelectSupplierPage() { InitializeComponent(); BindingContext = new SelectSupplierPageViewModel(); } // 移除原有的OnAppearing和SetBindingContext方法
3. 验证导航参数传递
保留可选的测试弹窗,方便后续验证参数是否正确传递:
public ICommand SelectSectionCommand => new Command<Rayon>(async (section) => { if (section?.Id == 0) return; // await Shell.Current.DisplayAlert("测试", $"传递的ID: {section.Id}", "确定"); await Shell.Current.GoToAsync($"{nameof(SelectSupplierPage)}?SectionId={section.Id}"); });
原代码失效原因
SetBindingContext中通过Create方法同步初始化ViewModel并调用API时,Shell还未完成QueryProperty的赋值,此时SectionId为默认值0。- 当Shell后续将正确的
SectionId赋值给ViewModel时,原代码未监听属性变化,因此不会重新调用API加载正确数据。
内容的提问来源于stack exchange,提问作者Yassine El mesbahy
相关产品推荐
相关产品推荐

