C # HttpClient.PostAsJsonAsync () завершается ошибкой, даже если тот же самый запрос принимается при выполнении через PostMan - PullRequest
0 голосов
/ 30 апреля 2019

Я нашел похожие вопросы как здесь, так и на дискуссионном форуме Elastic , но, к сожалению, ни один из ответов не помог.

Я сейчас использую ElasticSearch 7.0.

Я хочу сделать массовый запрос на мой сервер ElasticSearch. Мой файл JSON содержит информацию, которая выглядит примерно так:

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

Каждая строка заканчивается LF переводом строки, а также есть дополнительный LF перевод строки в конце документа.

В C # вот как я делаю POST-запрос для моих больших данных:

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

И все же я продолжаю видеть это сообщение об ошибке:

{"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}

Как я могу исправить эту ошибку?

UPDATE:

Краткое описание того, как я считываю содержимое документа 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:

Я только что сделал массовый запрос с точно таким же содержимым, используя PostMan, и запрос был успешным. Тем не менее, сообщение об ошибке сохраняется, когда я делаю тот же массовый запрос в C #, используя httpClient.PostAsJsonAsync(...).

1 Ответ

1 голос
/ 30 апреля 2019

Я заработал, изменив мой код следующим образом:

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());
}

Обратите внимание, что я использую HttpClient.PostAsync() вместо HttpClient.PostAsJsonAsync(), с экземпляром StringContent, который задает "application/json" какего тип носителя.

Я посмотрел исходный код для HttpClient и заметил, что новый экземпляр JsonMediaTypeFormatter создается каждый раз, когда вызывается HttpClient.PostAsJsonAsync.

Поскольку мои POST запросы успешны, когда я делаю их через PostMan, проблема должна быть вызвана тем, как реализован PostAsJsonAsync().Я подозреваю, но не проверил, что проблема связана со свойствами по умолчанию в классе JsonMediaTypeFormatter.

Чтобы обойти проблему, я решил использовать Http.PostAsync() с правильно настроенным экземпляром StringContent.

И вот, теперь я могу отправлять массовые запросы на мой сервер ElasticSearch, используя C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...