1

我有一个控制器端点,它提供如下文件;

    [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 };
}

但是,当我反序列化为object(with JsonConvert.DeserializeObject<T>(responseContent))

ex.Message当我调试并尝试在我得到的监视窗口中评估时抛出错误

'解析值时遇到意外字符:%。路径“,第 0 行,位置 0。”

这种情况下的退货是 PDF 文件。谁能指导我哪里出错了?

4

3 回答 3

4

正如 TomTom 提到的,您不能将 PDF 转换为 json,PDF 不像文本或 json 文件。

因此,在 Blazor 中,您必须按照以下方式进行操作。

当您从端点取回结果时,它将是一个流。因此,您可以执行以下操作从端点获取流:

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

获得文件流后,您必须将其转换为 byte

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

一旦你把它放在字节数组中,它现在是数组格式,我们现在可以通过用户浏览器使用和下载它。您必须创建以下 js 来触发 Blazor 中的浏览器下载

在这里,我们基本上是在 HTML DOM 中创建一个锚点并触发一个点击事件(source):

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));
于 2020-07-10T14:07:49.087 回答
0

类似于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 和 InvokeAsync。

于 2020-08-13T20:23:03.393 回答
0

啊,指出了明显的,但你已经告诉我们错了:

这种情况下的退货是 PDF 文件。

看,PDF 文件不是 JSON。

您尝试使用 JSON 转换器反序列化 PDF 文件:

var 结果 = JsonConvert.DeserializeObject(responseContent);

我不确定你从哪里得到这个应该起作用的想法。PDF 不是 JSON。哎呀,甚至“ReadAsStringAsync()”可能没有任何意义——我什至不确定 PDF 是否完全异步。它绝对不是 JSON。

于 2020-07-10T13:47:55.727 回答