You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将HttpResponseMessage保存为二进制至SQLite并供用户查看?

二进制附件存储SQLite及查看实现方案

一、问题根源

你当前代码存成JSON的核心原因:API返回的不是直接的文件二进制流,而是序列化后的HttpResponseMessage JSON字符串(也就是你给出的示例内容)。这时候调用ReadAsByteArrayAsync()拿到的是JSON的字节数据,而非真实文件的二进制。

二、修正二进制存储代码

1. 定义JSON解析模型

先把API返回的JSON结构对应成C#类,方便解析文件元数据:

public class HttpResponseMessageDto
{
    public string Version { get; set; }
    public ContentDto Content { get; set; }
    public int StatusCode { get; set; }
    public string ReasonPhrase { get; set; }
    public List<HeaderDto> Headers { get; set; }
    public List<HeaderDto> TrailingHeaders { get; set; }
    public object RequestMessage { get; set; }
    public bool IsSuccessStatusCode { get; set; }
}

public class ContentDto
{
    public List<HeaderDto> Headers { get; set; }
}

public class HeaderDto
{
    public string Key { get; set; }
    public List<string> Value { get; set; }
}

2. 正确获取并保存文件二进制

修改请求逻辑,先解析JSON拿到文件信息,再获取真实的文件二进制流:

var getFiles = new HttpRequestMessage(HttpMethod.Get, $"{Constants.getTicketApi}/{data.Id}/Document?filename={filename}");
HttpResponseMessage fileresponse = await _httpClient.SendAsync(getFiles);

if (fileresponse.IsSuccessStatusCode)
{
    // 读取并解析API返回的JSON
    var responseJson = await fileresponse.Content.ReadAsStringAsync();
    var responseDto = JsonSerializer.Deserialize<HttpResponseMessageDto>(responseJson);

    // 提取文件名和内容类型
    var dispositionHeader = responseDto.Content.Headers.FirstOrDefault(h => h.Key == "Content-Disposition")?.Value.FirstOrDefault();
    var fileName = dispositionHeader?.Split("filename=\"")[1].TrimEnd('"');
    var contentType = responseDto.Content.Headers.FirstOrDefault(h => h.Key == "Content-Type")?.Value.FirstOrDefault();

    // 重新请求获取真实文件二进制(告诉服务器返回二进制而非JSON)
    var fileRequest = new HttpRequestMessage(HttpMethod.Get, $"{Constants.getTicketApi}/{data.Id}/Document?filename={filename}");
    fileRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
    HttpResponseMessage fileStreamResponse = await _httpClient.SendAsync(fileRequest);

    if (fileStreamResponse.IsSuccessStatusCode)
    {
        var fileBytes = await fileStreamResponse.Content.ReadAsByteArrayAsync();

        FilesDB file = new FilesDB
        {
            TicketId = data.Id,
            FileDescriptorID = fdId,
            Data = fileBytes,
            FileName = fileName, // 建议额外存储文件名和类型,方便后续查看
            ContentType = contentType
        };

        await _context.SaveData(file);
    }
}
await _context.SaveData(filedescriptor);

3. 配置SQLite表结构

确保FilesDB对应的SQLite表中,Data字段类型为BLOB(二进制大对象),用EF Core配置的话:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<FilesDB>()
        .Property(f => f.Data)
        .HasColumnType("BLOB");
}

三、实现用户打开查看功能

1. 从SQLite读取文件数据

public async Task<FilesDB> GetFileById(int fileId)
{
    return await _context.FilesDB.FirstOrDefaultAsync(f => f.Id == fileId);
}

2. 分平台实现打开逻辑

桌面端(WPF/WinForms)

var file = await GetFileById(selectedFileId);
// 写入临时文件
var tempPath = Path.Combine(Path.GetTempPath(), file.FileName);
File.WriteAllBytes(tempPath, file.Data);
// 调用系统默认程序打开
Process.Start(new ProcessStartInfo(tempPath) { UseShellExecute = true });

移动端(Xamarin/.NET MAUI)

var file = await GetFileById(selectedFileId);
// 保存到应用缓存目录
var tempFile = Path.Combine(FileSystem.CacheDirectory, file.FileName);
File.WriteAllBytes(tempFile, file.Data);
// 调用系统打开文件
await Launcher.OpenAsync(new OpenFileRequest
{
    File = new ReadOnlyFile(tempFile),
    ContentType = file.ContentType
});

Web端(ASP.NET Core)

在控制器中提供文件下载/打开接口:

[HttpGet("file/{fileId}")]
public async Task<IActionResult> OpenFile(int fileId)
{
    var file = await _context.FilesDB.FirstOrDefaultAsync(f => f.Id == fileId);
    if (file == null) return NotFound();
    return File(file.Data, file.ContentType, file.FileName);
}

前端通过链接打开:

<a href="/api/file/1" target="_blank">打开文件</a>

内容的提问来源于stack exchange,提问作者Jean Ivan Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:03:14