我有一个控制器端点,它提供如下文件;
[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
时,此操作效果良好,并且可以确认文件已成功发送。
我想在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
(使用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。