不使用ViewModel的MAUI参数传递问题求助(含DI场景)
MAUI Shell导航传递对象时QueryProperty返回null的问题
我在页面中编写了如下代码用于导航并传递对象:
await Shell.Current.GoToAsync(nameof(Pages.StartPage), true, new Dictionary<string, object> { { "LoginData", result } });
其中result是一个自定义类对象。
我希望在Pages.StartPage中获取该对象,尝试使用[QueryProperty]特性但始终返回null,示例代码如下:
[QueryProperty(nameof(GetLoginData), "LoginData")] public partial class StartPage : ContentPage ... private JsonApiResult GetLoginData { set { _loginData = value; } }
我刚开始使用MAUI,正在将应用从Xamarin迁移至MAUI。现有页面可自主运行,因此不想使用ViewModel,仅需从传入对象中获取值供页面使用,除非万不得已不想重写所有页面。
更新
补充说明:我还在使用依赖注入(Dependency Injection,DI),这让问题更复杂了。
问题排查与解决办法
1. 修正QueryProperty的属性访问权限
你的GetLoginData属性是私有的,MAUI Shell导航无法访问私有属性完成赋值,必须改为公共属性,同时建议命名更直观(避免和方法命名混淆):
[QueryProperty(nameof(LoginData), "LoginData")] public partial class StartPage : ContentPage { private JsonApiResult _loginData; // 改为公共属性,可添加getter方便页面内部调用 public JsonApiResult LoginData { set { _loginData = value; } get { return _loginData; } } }
2. 确保对象支持序列化
MAUI Shell传递复杂对象时,默认要求对象可序列化。如果JsonApiResult类未做序列化标记,会导致传递失败:
- 给类添加
[Serializable]特性:[Serializable] public class JsonApiResult { // 类成员 } - 若不想修改类结构,可手动用JSON序列化传递:
发送端:
接收端:var json = JsonSerializer.Serialize(result); await Shell.Current.GoToAsync($"{nameof(Pages.StartPage)}?LoginData={Uri.EscapeDataString(json)}");[QueryProperty(nameof(LoginDataJson), "LoginData")] public partial class StartPage : ContentPage { private JsonApiResult _loginData; public string LoginDataJson { set { if (!string.IsNullOrEmpty(value)) { _loginData = JsonSerializer.Deserialize<JsonApiResult>(Uri.UnescapeDataString(value)); } } } }
3. 绕过QueryProperty,直接在生命周期取参数
如果DI导致Shell实例化页面的时机影响了QueryProperty赋值,可在页面的OnNavigatedTo方法中手动提取参数:
protected override void OnNavigatedTo(NavigatedToEventArgs args) { base.OnNavigatedTo(args); if (Navigation.Parameter is Dictionary<string, object> parameters && parameters.ContainsKey("LoginData")) { _loginData = parameters["LoginData"] as JsonApiResult; } }
这种方式无需依赖QueryProperty,直接从导航参数中读取,适配DI场景更稳定。
4. 确认Shell路由已注册
在AppShell.xaml中检查是否正确注册了StartPage的路由,否则Shell无法识别目标页面:
<ShellContent Route="StartPage" ContentTemplate="{DataTemplate local:StartPage}" />
内容的提问来源于stack exchange,提问作者djack109
相关产品推荐
相关产品推荐

