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

iOS 17下Xamarin.Forms URL编码异常问题求助

解决iOS 17下Xamarin.Forms GET请求URL中?被替换为%的问题

问题根源

iOS 17对URL解析逻辑做了更严格的规范,当直接将包含?的相对路径字符串传入HttpRequestMessage时,系统会错误地将?编码为%3F(表现为你看到的%截断),导致请求路径无效。

解决方案

以下是几种可行的修复方式,按推荐优先级排序:


1. 使用UriBuilder构建完整请求URL(推荐)

通过UriBuilder拆分Base地址、路径和查询参数,确保URL被正确解析:

var client = new HttpClient { BaseAddress = baseAddress };
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

if (receivedMethod == APIMethodConstants.GET)
{
    // 构建完整URL
    var uriBuilder = new UriBuilder(client.BaseAddress);
    uriBuilder.Path = Path.Combine(uriBuilder.Path, "requests"); // 替换为你的接口路径
    
    // 添加查询参数
    var queryParams = HttpUtility.ParseQueryString(string.Empty);
    queryParams["orderBy"] = "-created_at";
    queryParams["related"] = "user,+role";
    queryParams["perPage"] = "100";
    uriBuilder.Query = queryParams.ToString();

    req = new HttpRequestMessage(HttpMethod.Get, uriBuilder.Uri);
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", JwtToken);
    
    // 执行请求(替换原Task.Run+Wait的阻塞写法)
    stringObtained = await Threading(client, req);
    jsonObtained = stringObtained;
}

2. 拆分相对路径与查询参数

如果需要保留相对路径的方式,手动拆分路径和查询参数,构造合法的Uri对象:

if (receivedMethod == APIMethodConstants.GET)
{
    // 拆分路径和查询参数
    var relativePath = "requests";
    var queryDict = new Dictionary<string, string>
    {
        {"orderBy", "-created_at"},
        {"related", "user,+role"},
        {"perPage", "100"}
    };
    // 正确编码查询参数
    var queryString = string.Join("&", queryDict.Select(kv => 
        $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value)}"));
    
    // 构造相对Uri
    var relativeUri = new Uri($"{relativePath}?{queryString}", UriKind.Relative);
    req = new HttpRequestMessage(HttpMethod.Get, relativeUri);
    
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", JwtToken);
    stringObtained = await Threading(client, req);
    jsonObtained = stringObtained;
}

3. 移除无效代码

你的Threading方法中,WebUtility.UrlDecode(req.RequestUri.ToString());这行代码完全无效——它仅返回解码后的字符串,但并未修改req的实际请求Uri,直接删除即可:

async Task<string> Threading(HttpClient client, HttpRequestMessage req)
{
    // 删掉这行无用代码
    // WebUtility.UrlDecode(req.RequestUri.ToString());
    
    var resp = await client.SendAsync(req);
    switch (resp.StatusCode)
    {
          // rest logic
    }
    return stringObtained;
}

额外建议

  • 避免使用Task.Run(async () => await Threading(...) + task.Wait()的组合,直接用async/await可以避免线程阻塞问题
  • 始终通过Uri对象或UriBuilder构造请求地址,而非直接拼接字符串,减少编码异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:46:23