简体   繁体   English

C#HttpClient.PostAsJsonAsync()失败,即使通过PostMan发出的请求是完全相同的请求

[英]C# HttpClient.PostAsJsonAsync() fails, even though the exact same request is accepted when made through PostMan

I have found similar questions both here as well as on the Elastic discussion forum , but unfortunately none of the answers helped. 我在这里以及在Elastic讨论论坛上都发现了类似的问题,但是不幸的是,所有答案都无济于事。

I am currently using ElasticSearch 7.0 . 我目前正在使用ElasticSearch 7.0

I want to make a bulk request to my ElasticSearch server. 我想向我的ElasticSearch服务器发出批量请求。 My JSON file contains information that looks something like this: 我的JSON文件包含看起来像这样的信息:

{ "index": { "_index": "website", "_id": "link1" }}
{ "label":    "Link1" }

Each line is terminated by an LF line break, and there is also an additional LF line break at the end of the document. 每行以LF换行符终止,并且在文档末尾还有一个额外的LF换行符。

In C#, here is how I make a POST request for my bulk data: 在C#中,这是我对批量数据发出POST请求的方式:

HttpResponseMessage response = await httpClient.PostAsJsonAsync($"http://127.0.0.1:9200/website/_bulk", jsonDocumentContents);

And yet I keep seeing this error message: 但是我仍然看到此错误消息:

{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"}],"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"},"status":400}

How can I fix this error? 如何解决此错误?

UPDATE: 更新:

A short description of how I read the JSON document contents into the jsonDocumentContents variable: The JSON document was stored inside a zipped folder, so retrieving it requires unzipping: 关于如何将JSON文档内容读入jsonDocumentContents变量的简短描述:JSON文档存储在一个压缩文件夹中,因此要检索它,需要解压缩:

ZipArchive archive = new ZipArchive(zippedFolderStream);
foreach (ZipArchiveEntry entry in archive.Entries)
{
    string jsonDocumentContents = new StreamReader(entry.Open()).ReadToEnd();
    HttpResponseMessage response = await httpClient.PostAsJsonAsync($"http://127.0.0.1:9200/website/_bulk", jsonDocumentContents);
    Console.WriteLine(await response.Content.ReadAsStringAsync());
}

UPDATE: 更新:

I just made a bulk request with the exact same contents using PostMan, and the request was successful. 我只是使用PostMan发出了一个内容完全相同的批量请求,请求成功。 However, the error message persists when I make the same bulk request in C# using httpClient.PostAsJsonAsync(...) . 但是,当我使用httpClient.PostAsJsonAsync(...)在C#中进行相同的批量请求时,错误消息仍然存在。

I got it working by changing my code to the following: 我通过将代码更改为以下内容来使其工作:

ZipArchive archive = new ZipArchive(zippedFolderStream);
foreach (ZipArchiveEntry entry in archive.Entries)
{
    string jsonDocumentContents = new StreamReader(entry.Open()).ReadToEnd();
    StringContent content = new StringContent(jsonDocumentContents, Encoding.ASCII, mediaType: "application/json");
    HttpResponseMessage response = await httpClient.PostAsync($"http://127.0.0.1:9200/website/_bulk", content);
    Console.WriteLine(await response.Content.ReadAsStringAsync());
}

Notice that I am using HttpClient.PostAsync() instead of HttpClient.PostAsJsonAsync() , with a StringContent instance that specifies "application/json" as its media type. 请注意,我使用的是HttpClient.PostAsync()而不是HttpClient.PostAsJsonAsync() ,其StringContent实例将"application/json"指定为其媒体类型。

I looked into the source code for HttpClient , and noticed that a new instance of JsonMediaTypeFormatter is created every time HttpClient.PostAsJsonAsync is called. 我查看了HttpClient源代码 ,并注意到每次调用HttpClient.PostAsJsonAsync都会创建一个新的JsonMediaTypeFormatter实例。

Since my POST requests are successful when I make them through PostMan, the issue must be caused by how PostAsJsonAsync() is implemented. 由于我通过PostMan发出POST请求时成功,因此该问题必须由实现PostAsJsonAsync()引起。 I suspect, but have not verified, that the problem is due to the default properties in the JsonMediaTypeFormatter class. 我怀疑但尚未验证,问题是由于JsonMediaTypeFormatter类中的默认属性JsonMediaTypeFormatter

To circumvent the problem I decided to use Http.PostAsync() with a correctly-configured StringContent instance. 为了避免该问题,我决定将Http.PostAsync()与正确配置的StringContent实例一起使用。

Lo and behold, I can now send bulk requests to my ElasticSearch server using C#. 瞧,我现在可以使用C#将批量请求发送到我的ElasticSearch服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM