Как сохранить данные потока из внешнего запроса GET в .NET

В настоящее время я нахожусь в своем бэкэнде .NET (C#) и делаю вызов GET на внешний URL-адрес, который возвращает responseType: 'stream'. В этом случае происходит потоковая передача обратно данных, которые после завершения должны представлять собой действительный файл .PDF. Вызов этого внешнего API из Postman работает нормально и отображает PDF-файл, но мой код, похоже, не получает все потоковые данные, что приводит к созданию недопустимого файла.

Вот моя функция:

private async Task<string?> ReadFileData(string url)
{
    string fileData = null;

        using (var response = await _httpClient.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            var stream = await response.Content.ReadAsStreamAsync();
            fileData += await response.Content.ReadAsStringAsync();
        }

        return fileData;
    }

Это всего лишь одна из вещей, которые я пробовал, но, похоже, я не передаю в потоковом режиме весь набор данных, хотя я получаю первые 15 или около того строк PDF-файла, который должен состоять из нескольких сотен строк (необработанного текста), я сделал довольно много исследований, но, похоже, ничего не нашел. Я уверен, что упускаю что-то глупое относительно потоковой передачи данных, если у кого-нибудь есть какие-либо подстрекательства, это было бы здорово.

Попробуйте fileData = await response.Content.ReadAsStringAsync(); вместо +=

Mykhailo Svyrydovych 03.07.2024 00:03

Знаете ли вы, какой ответ он возвращает или тип данных вы видели в почтальоне?

Md Farid Uddin Kiron 03.07.2024 03:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это всего лишь одна из вещей, которые я пробовал, но, похоже, я не транслирую весь набор данных, хотя я получаю первые 15 или около того строк того, что должен быть PDF-файл, состоящий из нескольких сотен строк (необработанного текста), я сделал довольно много исследований, но, похоже, ничего не нашел.

В соответствии с вашим сценарием и описанием, а также общим фрагментом кода я попытался устранить вашу проблему.

Судя по моему тесту, проблема в вашем коде заключается в том, как вы обрабатываете содержимое ответа. Вы пытаетесь прочитать содержимое как строку, которая не подходит для двоичных данных, таких как файл PDF. Вместо этого вам необходимо правильно обрабатывать поток.

Чтобы это исправить, считайте данные потока с помощью ReadAsStreamAsync в MemoryStream, а затем преобразуйте их в byte array, который затем можно обработать или сохранить по мере необходимости. Вот как вы можете вызвать метод ReadFileDataAsync и при необходимости сохранить данные в файл:

[Route("api/[controller]")]
[ApiController]
public class FileAccessController : ControllerBase
{
    private readonly HttpClient _httpClient;

    public FileAccessController(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient();
    }

    [HttpGet("download-file")]
    public async Task<IActionResult> DownloadFile(string url)
    {
        try
        {
            //Passing the url to the file content reading method
            byte[] fileData = await ReadFileDataAsync(url);

            // I am Returning the file as a FileResult
            return File(fileData, "application/pdf", "downloaded-file.pdf");
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"An error occurred: {ex.Message}");
        }
    }

    private async Task<byte[]> ReadFileDataAsync(string url)
    {
        using (var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
        {
            response.EnsureSuccessStatusCode();

            using (var stream = await response.Content.ReadAsStreamAsync())
            using (var memoryStream = new MemoryStream())
            {
                await stream.CopyToAsync(memoryStream);
                return memoryStream.ToArray();
            }
        }
    }
}

Выход:

Примечание. Следуя вышеизложенному, у вас есть полные данные PDF в файлеData, которые вы можете использовать по мере необходимости. Если вам не нужно сохранять его в файл, вы можете использовать массив байтов fileData непосредственно в своем приложении. Пожалуйста обратитесь к этому официальному документу, если вам нужна дополнительная помощь.

Я хочу сказать, что это отличный ответ, хотя у меня все еще есть некоторая потеря данных, когда byte[] по какой-то причине преобразуется в строку. Если я пишу через WriteAllBytes(), у него есть действительный хороший PDF-файл, но если я преобразую его в строку, он испортится. Возможно, мне не хватает информации о преобразовании строк. Может быть, кодировка по умолчанию неправильная?

Dohrann 03.07.2024 15:53

Привет, спасибо за ваш ответ. При работе с двоичными файлами, такими как PDF-файлы, важно помнить, что эти файлы не следует рассматривать как текст. Преобразование двоичных данных в строку и обратно может привести к потере данных из-за проблем с кодировкой. Вместо этого вам следует обращаться с ними как с двоичными данными на протяжении всего процесса. Если вам нужно манипулировать двоичным файлом, например PDF, избегайте его преобразования в строку.

Md Farid Uddin Kiron 03.07.2024 17:15

Другие вопросы по теме