VB.NET集成Google Places新API遇TaskCanceledException问题求助
解决VB.NET调用Google Places API v1的TaskCanceledException及400错误问题
问题分析
TaskCanceledException大多因请求超时或HttpClient实例未正确复用导致;Postman正常但代码报错,说明请求逻辑存在细节疏漏。- 第二种
WebRequest方式报400错误,是因为错误地将textQuery放在请求头,而非官方要求的JSON请求体中。
解决方案及修正代码
1. 正确复用HttpClient并设置超时
HttpClient应全局复用(而非每次请求新建),同时可延长超时时间避免请求被取消:
' 全局复用的HttpClient实例(建议在类级别声明) Private Shared ReadOnly _httpClient As New HttpClient() With { .Timeout = TimeSpan.FromSeconds(30) ' 设置30秒超时,可根据需求调整 } Async Function SearchPlacesAsync() As Task Try Dim request = New HttpRequestMessage(HttpMethod.Post, "https://places.googleapis.com/v1/places:searchText") ' 添加API密钥和字段掩码请求头 request.Headers.Add("X-Goog-Api-Key", My.Settings.APIKey_Google) request.Headers.Add("X-Goog-FieldMask", "places.displayName,places.formattedAddress,places.businessStatus,places.location,places.types,places.rating,places.userRatingCount") ' 使用对象序列化生成JSON请求体(避免手动拼接出错) Dim requestBody = New With { .textQuery = "B&B in San Marzano sul Sarno SA, Campania" } Dim jsonContent = JsonSerializer.Serialize(requestBody) Dim content = New StringContent(jsonContent, Encoding.UTF8, "application/json") request.Content = content Dim response = Await _httpClient.SendAsync(request) response.EnsureSuccessStatusCode() ' 确保请求返回成功状态码 Dim result = Await response.Content.ReadAsStringAsync() Console.WriteLine(result) Catch ex As TaskCanceledException Console.WriteLine("请求超时或被取消:" & ex.Message) Catch ex As HttpRequestException Console.WriteLine("请求错误:" & ex.Message) Catch ex As Exception Console.WriteLine("未知错误:" & ex.Message) End Try End Function
2. 修复WebRequest方式的错误
若坚持使用WebRequest,需将textQuery放入JSON请求体,而非请求头:
Dim apiKey As String = My.Settings.APIKey_Google Dim request As WebRequest = WebRequest.Create("https://places.googleapis.com/v1/places:searchText") request.Method = "POST" request.ContentType = "application/json" request.Headers.Add("X-Goog-Api-Key", apiKey) request.Headers.Add("X-Goog-FieldMask", "places.displayName") ' 构造JSON请求体 Dim requestBody = "{""textQuery"": ""Parrucchieri in San Marzano sul Sarno SA, Campania""}" Dim byteArray = Encoding.UTF8.GetBytes(requestBody) request.ContentLength = byteArray.Length ' 将请求体写入流 Using dataStream As Stream = request.GetRequestStream() dataStream.Write(byteArray, 0, byteArray.Length) End Using Try Using response As WebResponse = request.GetResponse() Using reader As New StreamReader(response.GetResponseStream()) Dim result = reader.ReadToEnd() Console.WriteLine(result) End Using End Using Catch ex As Exception Console.WriteLine("错误:" & ex.Message) End Try
关键注意事项
- HttpClient复用:频繁创建
HttpClient会耗尽套接字资源,导致请求异常,全局复用是最佳实践。 - 请求体格式:手动拼接JSON易出现语法错误,建议使用
System.Text.Json或Newtonsoft.Json序列化对象生成请求体。 - 参数位置:
textQuery必须放在POST请求的JSON体中,不能放在请求头,否则会触发400无效请求错误。 - 超时设置:默认超时时间可能不足以完成API请求,需根据网络情况调整超时时长。
内容的提问来源于stack exchange,提问作者Giovanni D'Elia
相关产品推荐
相关产品推荐

