如何使用RestSharp v107上传NDJSON文件发起POST请求
问题背景
我正在尝试使用RestSharp(v107版本)实现与下述cURL命令等效的功能,目标是调用Elasticsearch的批量导入接口:
curl --insecure -H "Content-Type: application/x-ndjson" -XPOST -u user:password https://localhost:9200/products/_bulk --data-binary "@pathtofile/products-bulk.json"
其中products-bulk.json是NDJSON格式文件,内容为多个换行符分隔的JSON对象。
最初编写的实现代码如下:
string base_url = "https://localhost:9200"; // 禁用SSL证书验证(仅本地测试使用) var options = new RestClientOptions(base_url) { RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true }; var client = new RestClient(options); string username = "user"; string password = "password"; client.Authenticator = new HttpBasicAuthenticator(username, password); var request = new RestRequest() ; request.Method = Method.Post; request.Resource = "products/_bulk"; request.RequestFormat = DataFormat.Binary; // 尝试模拟--data-binary格式 request.AddHeader("Content-Type", "application/ndjson"); string path = @"pathtofile\products-bulk.json"; request.AddFile("file",path); var response = client.Execute(request);
运行后抛出406错误:
{"error":"Content-Type header [application/ndjson; boundary="03713f22-b45c-40ed-a9f6-50949a99a017"] is not supported","status":406}
尝试过网传方案:将Content-Type改为application/json,同时在RestClientOptions中指定iso-8859-1编码,但方案无效,会触发其他错误。
问题根因
报错核心原因有两个:
- 错误使用
AddFile方法上传文件:该方法会自动将请求编码为multipart/form-data表单格式,RestSharp会自动在Content-Type头后追加boundary=xxx的分隔符参数,而Elasticsearch的_bulk接口仅接受纯NDJSON格式的原始请求体,不支持multipart表单格式。 - Content-Type取值错误:Elasticsearch批量接口要求的NDJSON媒体类型是
application/x-ndjson,不是代码中写的application/ndjson。
你设置的RequestFormat = DataFormat.Binary不会覆盖AddFile触发的表单编码逻辑,因此不生效。
修复后的实现代码
直接读取NDJSON文件的原始内容作为请求体发送,不要使用表单上传逻辑,小体积文件可以直接读取文本内容传入:
string base_url = "https://localhost:9200"; // 本地测试跳过SSL证书验证,生产环境请替换为合法证书校验逻辑 var options = new RestClientOptions(base_url) { RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true }; var client = new RestClient(options); string username = "user"; string password = "password"; client.Authenticator = new HttpBasicAuthenticator(username, password); var request = new RestRequest("products/_bulk", Method.Post); string filePath = @"pathtofile\products-bulk.json"; // 读取NDJSON文件原始内容 string ndjsonContent = File.ReadAllText(filePath); // 直接将原始内容作为请求体传入,指定正确的Content-Type request.AddStringBody(ndjsonContent, "application/x-ndjson"); var response = client.Execute(request);
如果是GB级别的大体积bulk文件,为了避免一次性加载整个文件占用过高内存,可以用流的方式传递请求体:
// 大文件场景替换AddStringBody为下面的流传递逻辑 request.AddStreamBody(() => File.OpenRead(filePath), "application/x-ndjson");
额外注意事项
- 确保你的
products-bulk.json文件末尾保留一个空行,Elasticsearch的_bulk接口要求所有行都必须以换行符结尾,否则会抛出JSON解析错误。 - 不要给
application/x-ndjson追加charset等多余参数,部分版本的Elasticsearch对Content-Type校验非常严格,多余参数会触发406错误。 - 调用完成后可以通过
response.IsSuccessful属性判断请求是否成功,通过response.Content查看接口返回的详细报错信息。
内容的提问来源于stack exchange,提问作者Vignesh
相关产品推荐
相关产品推荐

