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

Xamarin Shell传递含#号的JSON字符串时数据截断问题

Xamarin.Forms Shell 导航传参含#时被截断问题

问题场景

  • 标准Xamarin.Forms项目,采用模板页展示概览数据,用户点击条目后跳转至详情页
  • 数据从服务端API拉取,点击条目时通过JsonConvert.SerializeObject序列化参数,拼接在路由查询字符串中传递给详情页
  • 常规数据下流程运行正常,当数据中包含#(哈希符/井号)时,详情页接收到的JSON字符串会在#出现的位置直接截断

模板页点击传参核心代码

var forminfo = JsonConvert.SerializeObject(ea.Parameter);
Routing.RegisterRoute(nameof(TrackWarrantPageX), typeof(TrackWarrantPageX));
await Shell.Current.GoToAsync($"{nameof(TrackWarrantPageX)}?{nameof(TrackWarrantPageX.Contentx)}={forminfo}");

详情页接收参数核心代码

[XamlCompilation(XamlCompilationOptions.Compile)]
[QueryProperty(nameof(Contentx), nameof(Contentx))]
public partial class TrackWarrantPageX : ContentPage
{
    string contentx = "";
    public string Contentx
    {
        get => contentx;
        set
        {
            contentx = Uri.UnescapeDataString(value ?? string.Empty);
            OnPropertyChanged();
            PopulateForm(contentx); // 此处调试检查时,参数内容已被截断
        }
    }
}

问题根因

URI语法规范中,#是片段标识符的起始标记,Shell执行路由解析时,会默认将#及后续内容识别为页面锚点片段,不会作为查询参数的一部分传入目标页面,因此会出现截断。除#外,&、?、=、/等URI保留字符出现在未编码的参数值中时,同样会引发参数解析错误。

解决方案

方案1:对查询参数做URI编码(兼容现有逻辑)

拼接路由前,对序列化后的JSON字符串调用Uri.EscapeDataString做数据编码,将所有URI保留字符转换为合法的转义序列,避免解析器误判。
修改传参代码如下:

var forminfo = JsonConvert.SerializeObject(ea.Parameter);
// 对参数值做URI编码,转义所有特殊保留字符
var encodedFormInfo = Uri.EscapeDataString(forminfo);
Routing.RegisterRoute(nameof(TrackWarrantPageX), typeof(TrackWarrantPageX));
await Shell.Current.GoToAsync($"{nameof(TrackWarrantPageX)}?{nameof(TrackWarrantPageX.Contentx)}={encodedFormInfo}");
  • 详情页现有Uri.UnescapeDataString处理逻辑可保留,无需修改,编码后的参数经路由解析后会自动完成一次解码,手动解码不会引发异常。

方案2:使用对象传参重载(推荐,从根源规避特殊字符问题)

如果传递的数据结构复杂、体积较大,不需要手动序列化拼接查询字符串,直接使用Shell导航的对象传参重载即可,完全不受特殊字符、参数长度限制,是官方推荐的复杂参数传递方式。
修改传参代码如下:

// 构造导航参数字典,可直接传递序列化后的字符串,也可直接传递原始对象
var navParams = new Dictionary<string, object>
{
    [nameof(TrackWarrantPageX.Contentx)] = JsonConvert.SerializeObject(ea.Parameter)
};
Routing.RegisterRoute(nameof(TrackWarrantPageX), typeof(TrackWarrantPageX));
await Shell.Current.GoToAsync(nameof(TrackWarrantPageX), navParams);

该方案下参数不会经过URI解析流程,不会出现特殊字符截断问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:27:33