Xamarin Shell路由导航注入Action到视图模型及ContentThread为空问题
问题根因与解决方法
1. URI特殊字符截断导致参数丢失
你直接将序列化后的JSON字符串拼接到URI中,JSON包含的{、}、双引号、逗号等都是URI保留字符,Shell解析URI时会将这些字符识别为参数分隔符,直接截断ContentThread的参数值,最终属性赋值为null。而布尔类型的IsBooking转成字符串后无特殊字符,所以可以正常拿到值。
修复方法:对JSON字符串做URI编码后再拼接:
// 发送端编码 string actionJson = JsonConvert.SerializeObject(action); string encodedAction = Uri.EscapeDataString(actionJson); var uri = $"{nameof(Booking)}?ContentThread={encodedAction}&IsBooking=true";
接收端可手动解码:
string decodedAction = Uri.UnescapeDataString(ContentThread); var actions = JsonConvert.DeserializeObject<Action>(decodedAction);
2. System.Action委托无法正常序列化
System.Action属于委托类型,Newtonsoft.Json默认无法序列化委托的执行上下文,就算能拿到完整的JSON字符串,反序列化后的委托也无法正常执行原页面的SendBook方法。
正确实现方案:直接使用Shell的对象传参重载,不需要走URI拼接和序列化:
// 发送端直接传对象参数 var parameters = new Dictionary<string, object> { {"ContentThread", new Action(() => SendBook(true))}, {"IsBooking", true} }; Routing.RegisterRoute(nameof(Booking), typeof(Booking)); await Shell.Current.GoToAsync(nameof(Booking), parameters);
这种方式直接传递引用对象,完全规避转义和序列化问题,回调可以正常执行。
3. 属性未实现变更通知导致注入失效(部分版本框架要求)
如果使用MAUI/Xamarin.Forms的低版本,要求接收QueryProperty的属性实现INotifyPropertyChanged接口才能正常触发赋值,你可以将属性调整为支持通知的写法:
// 用CommunityToolkit.Mvvm的写法 [ObservableProperty] private string _contentThread; [ObservableProperty] private bool _isBooking;
不需要工具包的话手动实现INotifyPropertyChanged即可。
内容的提问来源于stack exchange,提问作者DevQc
相关产品推荐
相关产品推荐

