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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:49:50