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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:33:21