使用并反序列化FileStreamResult Blazor



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

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

当在img标记上设置为src时,此操作效果良好,并且可以确认文件已成功发送。

我想在blazorrazor页面中使用结果。我使用取消了呼叫的分类

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(使用JsonConvert.DeserializeObject<T>(responseContent)(时

当我调试并试图在观察窗口中评估时,抛出了一个没有ex.Message的错误。我得到了

'分析值时遇到意外字符:%。路径",行0,位置0。

在这种情况下返回的是一个PDF文件。有人能告诉我哪里出了问题吗?

正如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 中触发浏览器下载

在这里,我们基本上是在HTMLDOM中创建一个锚点,并触发一个点击事件(来源(:

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

啊,指出了显而易见的,但你已经告诉我们什么是错误的:

在这种情况下返回的是一个PDF文件。

请注意,PDF文件不是JSON。

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

var result=JsonConvert。反序列化对象(responseContent(;

我不确定你从哪里得到了这样的想法。PDF不是JSON。见鬼;ReadAsStringAsync(("可能没有任何意义——我甚至不确定PDF是否完全异步。它绝对不是JSON。

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

相关内容

  • 没有找到相关文章

最新更新