使用C#向Geocod.io API上传带参数文件时遇400错误求助
问题排查:Geocod.io API批量地理编码请求400错误
API要求的请求格式(curl示例)
curl "https://api.geocod.io/v1.7/lists?api_key=YOUR_API_KEY" \ -F "file"="@sample_list.csv" \ -F "direction"="forward" \ -F "format"="{{A}} {{B}} {{C}} {{D}}"
报错的C#代码
var httpClient = new HttpClient(); var baseUri = "https://api.geocod.io/v1.7/lists?" using (var multipartFormContent = new MultipartFormDataContent()) { //set up the parameters var query = new Dictionary<string, string>() { ["api_key"] = "My_API_Key", ["direction"] = "forward", ["format"] = "{{C}} {{D}} {{E}} {{F}}" }; //base uri var uri = QueryHelpers.AddQueryString(baseUri, query); //load the file var memoryStream = new MemoryStream(); await csvFile.CopyToAsync(memoryStream); var fileStreamContent = new StreamContent(memoryStream); //add the file multipartFormContent.Add(fileStreamContent, name: "file", fileName: fileNameForStorage); //send it var response = await httpClient.PostAsync(uri, multipartFormContent); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); }
错误原因及修复方案
1. 参数传递位置错误
curl示例中,direction和format是作为multipart/form-data的表单字段(-F参数)传递的,但你的代码把它们放到了URL查询参数里,不符合API的接收要求,导致API无法正确解析这两个参数,触发400错误。
2. 文件流指针位置错误
将csvFile复制到MemoryStream后,流的当前位置停在末尾,StreamContent读取时会从当前位置开始,相当于读取空内容,API接收不到有效文件,也会返回400错误。
3. 缺少文件内容类型标记
没有为文件流设置正确的Content-Type(比如text/csv),API可能无法识别上传的文件类型,导致解析失败。
修改后的正确代码
var httpClient = new HttpClient(); var baseUri = "https://api.geocod.io/v1.7/lists?api_key=My_API_Key"; // api_key可保留在查询参数,也可放到form-data中 using (var multipartFormContent = new MultipartFormDataContent()) { // 将direction、format作为form-data字段添加 multipartFormContent.Add(new StringContent("forward"), "direction"); multipartFormContent.Add(new StringContent("{{C}} {{D}} {{E}} {{F}}"), "format"); // 处理文件流 var memoryStream = new MemoryStream(); await csvFile.CopyToAsync(memoryStream); memoryStream.Position = 0; // 重置流指针到开头 var fileStreamContent = new StreamContent(memoryStream); fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("text/csv"); // 设置CSV内容类型 // 添加文件到form-data multipartFormContent.Add(fileStreamContent, "file", fileNameForStorage); // 发送请求 var response = await httpClient.PostAsync(baseUri, multipartFormContent); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); }
补充说明
api_key既可以像curl示例那样放在URL查询参数里,也可以作为form-data字段传递,Geocod.io API两种方式都支持。- 确保
fileNameForStorage的后缀是.csv,避免API对文件类型产生误判。
内容的提问来源于stack exchange,提问作者Liz Nal
相关产品推荐
相关产品推荐

