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
相关产品推荐
相关产品推荐

