Использовать и десериализовать FileStreamResult Blazor - PullRequest
0 голосов
/ 10 июля 2020

У меня есть конечная точка контроллера, которая обслуживает файлы следующим образом:

    [HttpGet]
    [ProducesResponseType(typeof(FileStreamResult), 200)]
    [Route("{documentId}")]
    public IActionResult GetDocumentImage(int documentId)
    {
        var response = _service.Get(documentId);

        HttpAssert.Success(response);
        HttpAssert.IsNotNull(response);

        Stream stream = new MemoryStream(response.Result.Data);

        if (stream == null)
            return NotFound();

        return File(stream, response.Result.MimeType); 
    }

Это хорошо работает при установке src в теге img и может подтвердить, что файлы успешно отправлены.

Я хочу получить результат на странице blazor razor. Я десериализую вызов, используя

var responseContent = await response.Content.ReadAsStringAsync();

if (response.IsSuccessStatusCode)
{
 var result = JsonConvert.DeserializeObject<T>(responseContent);
 return new ServiceResponse<T> { Result = result, HasError = false, HttpErrorCode = -1, Error = null };
}

Однако, когда я десериализую до objectJsonConvert.DeserializeObject<T>(responseContent))

, при отладке и попытке выдается ошибка без ex.Message для оценки в окне просмотра я получаю

'При анализе значения обнаружен неожиданный символ:%. Путь '', строка 0, позиция 0. '

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

Ответы [ 3 ]

3 голосов
/ 10 июля 2020

Как упоминалось в TomTom, вы не можете преобразовать PDF в формат json, PDF не похож на текст или файл json.

Итак, в Blazor вам нужно будет сделать следующее.

Когда вы получите результат от конечной точки, это будет поток. Таким образом, вы можете сделать следующее, чтобы получить поток из конечной точки :

var fileStream = new FileStream()
{
    Stream = await httpResponseMessage.Content.ReadAsStreamAsync(),
    Filename = $"someFile.pdf"
};

После того, как вы получите поток файла, вам нужно преобразовать его в байт :

byte[] bytes;
using (var memoryStream = new System.IO.MemoryStream())
{
    fileStream.Stream.CopyTo(memoryStream);
    bytes = memoryStream.ToArray();
}

После того, как вы получили его в байтовом массиве, теперь он находится в формате массива, который теперь мы можем использовать и загружать через браузер пользователя. Вам нужно будет создать следующее js, чтобы запустить загрузку браузера в Blazor

Здесь мы в основном создаем привязку в HTML DOM и запускаем событие щелчка ( источник ) :

var saveAsFile = function (filename, bytesBase64) {
    var link = document.createElement('a');
    link.download = filename;
    link.href = "data:application/octet-stream;base64," + bytesBase64;
    document.body.appendChild(link); // Needed for Firefox
    link.click();
    document.body.removeChild(link);
}

Мы можем вызвать приведенный ниже код в Blazor c# и запустить его через JSInterop

await JsRunTime.InvokeAsync<object>("saveAsFile", fileStream.Filename,
    Convert.ToBase64String(bytes));
0 голосов
/ 13 августа 2020

Подобно ответу Umair , вместо создания нового FileStream и нового MemoryStream вы можете просто сделать это:

using var streamReader = new StreamReader(await httpResponseMessage.Content.ReadAsStreamAsync());
var fileString = await streamReader.ReadToEndAsync();
var bytes = Encoding.ASCII.GetBytes(fileString);

Затем по-прежнему следуйте примеру Umair JS Триггер Blazor код, вызывающий saveFileAs и InvokeAsyn c.

0 голосов
/ 10 июля 2020

Ах, указывая на очевидное, но вы уже говорите нам, что это неправильно:

В этой ситуации возвращается файл PDF.

См. Файл PDF - это не JSON.

Вы пытаетесь десериализовать файл PDF с помощью JSON Converter:

var result = JsonConvert.DeserializeObject (responseContent);

Я не уверен, откуда вы взяли, что это должно работать. PDF - это не JSON. Черт возьми, evn «ReadAsStringAsyn c ()» может не иметь никакого смысла - я даже не уверен, что PDF полностью асинхронный c. Это точно не JSON.

...