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

.NET MAUI Shell传递复杂JSON转义异常及导航传参方案咨询

两种导航方法的区别

Shell.Current.Navigation.PushAsync(new MediaDetailsPage(selectedAnimeMedia)) 是Xamarin.Forms/.NET MAUI保留的传统导航API,用于兼容旧版非Shell架构的导航逻辑,确实会将页面推入Shell的统一导航栈,后退逻辑和GoToAsync推入的页面完全一致。不需要提前注册路由的原因是你直接传递了实例化后的页面对象,Shell不需要通过路由名查找对应页面类型。

它和基于路由的GoToAsync核心差异如下:

  • GoToAsync是Shell专属的导航API,支持路由分层、相对/绝对路由跳转、导航参数统一解析传递,还可对接Shell的路由拦截、返回栈管理、深度链接等高级特性,要求跳转的页面提前在Shell路由表注册。
  • PushAsync是通用导航API,没有路由相关特性支持,你可以直接控制页面实例的创建,适合快速传递复杂对象的场景。只要你不需要使用依赖路由注册的特性(比如深度链接、路由拦截),该方法完全可以正常使用,官方没有弃用该API,后续版本也不会出现兼容性问题,目前大量实际项目都在采用这种用法。

Shell传递复杂对象的正确实现

你遇到的JSON转义错误,本质是因为GoToAsync的路由参数是拼接在URL里的,JSON内的特殊字符(双引号、斜杠、空格、换行符)会被URL转义逻辑修改,导致原有转义规则失效,绝对不推荐用URL拼接的方式传递长文本、JSON这类复杂内容。

目前主流的实现方式有三种,按推荐优先级排序:

  1. 优先使用你提到的PushAsync直接传参:直接在页面构造函数接收Media实例,不需要序列化/反序列化操作,完全不会出现转义问题,代码实现最简单也最稳定,如果你不需要用到深度链接、路由跳转高级特性,这是最优解。
  2. 如果你必须使用GoToAsync路由跳转,可以使用Shell原生的对象参数传递特性(.NET MAUI Preview 13及以上版本支持),不需要拼接URL,直接传递字典类型的参数即可:
    // 发送端
    var navigationParams = new Dictionary<string, object>
    {
        {"SelectedMedia", SelectedAnimeMedia }
    };
    await Shell.Current.GoToAsync(nameof(MediaDetailsPage), navigationParams);
    
    目标页面通过[QueryProperty]特性接收参数即可,不需要序列化操作,完全避免转义问题:
    [QueryProperty(nameof(CurrentMedia), "SelectedMedia")]
    public partial class MediaDetailsPage : ContentPage
    {
        private Media _currentMedia;
        public Media CurrentMedia
        {
            get => _currentMedia;
            set
            {
                _currentMedia = value;
                // 执行页面初始化逻辑
            }
        }
        // 页面其他逻辑
    }
    
  3. 如果你一定要使用JSON拼接URL的方式,必须先对序列化后的JSON做URL编码,接收后再做URL解码,才能避免转义被修改:
    // 发送端
    string rawJson = JsonConvert.SerializeObject(SelectedAnimeMedia);
    string encodedJson = Uri.EscapeDataString(rawJson);
    await Shell.Current.GoToAsync($"MediaDetailsPage?name={encodedJson}");
    
    // 接收端
    string receivedEncodedJson = 页面接收到的name参数值;
    string rawJson = Uri.UnescapeDataString(receivedEncodedJson);
    var media = JsonConvert.DeserializeObject<Media>(rawJson);
    

内容的提问来源于stack exchange,提问作者ziomek64

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:45:00