导航传参触发System.Reflection.TargetInvocationException问题排查
MAUI Shell返回导航传递复杂对象抛出TargetInvocationException的解决方法
在MAUI Shell导航场景中:从MainPage传递Test对象到Page1,Page1再传递该对象到Page2,修改Test属性后调用GoToAsync("..", parameters)返回Page1时,抛出System.Reflection.TargetInvocationException异常。
错误原因
Shell导航的参数机制默认会将参数转换为查询字符串传递,自定义复杂对象(如Test类)无法直接被序列化/反序列化为字符串,导致反射调用参数转换方法时触发异常。
解决方法
方法1:利用引用类型特性,无需传递参数
Test作为引用类型,从MainPage到Page1再到Page2传递的是同一个对象引用。Page2修改属性后,Page1中的Test实例属性会自动更新,直接返回即可:
修改Page2ViewModel的GoBackToPage1方法:
async void GoBackToPage1() { Test.TestProperty = "newValue"; // 直接返回,无需传递参数 await Shell.Current.GoToAsync(".."); }
方法2:序列化对象为JSON字符串传递
如果需要显式传递更新后的对象(比如对象是值类型,或者需要强制刷新),可以将对象序列化为JSON字符串,传递后再反序列化:
- 修改Page2ViewModel:
using System.Text.Json; async void GoBackToPage1() { Test.TestProperty = "newValue"; // 序列化为JSON字符串 var testJson = JsonSerializer.Serialize(Test); var parameters = new Dictionary<string, object> { { "Test", testJson } }; await Shell.Current.GoToAsync("..", parameters); }
- 修改Page1ViewModel的QueryProperty处理逻辑:
using System.Text.Json; [ObservableProperty] Test _test; // 新增用于接收JSON字符串的QueryProperty [QueryProperty(nameof(TestJson), "Test")] public string TestJson { set { if (!string.IsNullOrEmpty(value)) { // 反序列化为Test对象 Test = JsonSerializer.Deserialize<Test>(value); } } }
额外注意事项
- 确保
Test类是可序列化的:属性需为公共访问级别,若有特殊需求可添加JSON序列化特性。 - Shell导航中应避免直接传递复杂对象,优先使用引用共享或字符串序列化的方式。
内容的提问来源于stack exchange,提问作者Zoltán
相关产品推荐
相关产品推荐

