gpt4 book ai didi

c# - 如何将 azure blob 存储文件作为 FileStreamResult 返回?

转载 作者:行者123 更新时间:2023-12-03 04:40:12 24 4
gpt4 key购买 nike

我正在开发用于处理文件的 Web API。我正在尝试从 azure blob 存储下载文件并将其作为响应返回。对于开发 API,我使用 FastEndpoints

在 Stack Overflow 上,我发现最好的选择是使用 FileStreamResult,但我收到错误:

System.NotSupportedException: Deserialization of types without aparameterless constructor

我该如何解决这个问题以及为什么我会遇到这个问题?

端点

public class Endpoint : Endpoint<DownloadFileRequest, FileStreamResult>
{
private readonly DatabaseContext _context;
private readonly ILogger _logger;
private readonly IConfiguration _configuration;

public Endpoint(DatabaseContext context, ILogger<Endpoint> logger, IConfiguration configuration)
{
_context = context;
_logger = logger;
_configuration = configuration;
}

public override void Configure()
{
Get("/file/{id}/download");
Roles(Role.Administrator, Role.ProjectManager, Role.GraphicDesigner, Role.Accountant);
Description(b => b.WithName("DownloadFile"));
}

public override async Task HandleAsync(DownloadFileRequest r, CancellationToken c)
{
var file = await Data.GetTriadaFileAsync(_context, r.Id, c); // gets file to
// download

if (file == null)
{
await SendNotFoundAsync(c);
return;
}

var result = await Data.DownloadBlobAsync(file.AzureName, r, c, _configuration);

if (result != null)
{
Response.FileStream = result.FileStream;
}
}
}

数据

public static class Data
{
public static async Task<TriadaFile?> GetTriadaFileAsync(DatabaseContext context, Guid id, CancellationToken c)
{
return await context.Files
.FirstOrDefaultAsync(x => x.Id == id, c);
}
public static async Task<FileStreamResult?> DownloadBlobAsync(string blobFileName, DownloadFileRequest r, CancellationToken c, IConfiguration _configuration)
{
string connectionString = _configuration.GetSection("Azure").GetValue<string>("BlobConnectionString")!;
string containerName = _configuration.GetSection("Azure").GetValue<string>("BlobContainerName")!;

BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);

BlobClient blobClient = containerClient.GetBlobClient(blobFileName);

using (var stream = new MemoryStream())
{
await blobClient.DownloadToAsync(stream);
stream.Position = 0;
var contentType = (await blobClient.GetPropertiesAsync()).Value.ContentType;

var fileStreamResult = new FileStreamResult(stream, "application/octet-stream");

fileStreamResult.FileDownloadName = blobFileName;

return fileStreamResult;
}
}


}

模型

public class DownloadFileRequest
{
public Guid Id{ get; set; }
}

public class Validator : Validator<DownloadFileRequest>
{
public Validator()
{
RuleFor(x => x.Id)
.NotEmpty();
}
}

public class DownloadFileResponse
{


}

Question that helped me with me

最佳答案

问题是无论内容类型是什么,它总是将对象序列化为 JSON。所以我在 Program.cs 中像这样修复了它:

app.UseFastEndpoints(c =>
{
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);

c.Serializer.ResponseSerializer = (rsp, dto, cType, jCtx, ct) =>
{
// this condition allows any content type
if (dto is FileStreamResult fsr)
{
rsp.ContentType = fsr.ContentType;
rsp.Body = fsr.FileStream;

return rsp.SendStreamAsync(rsp.Body, fsr.FileDownloadName, null, fsr.ContentType); ;
}

rsp.ContentType = cType;
return rsp.WriteAsync(JsonSerializer.Serialize(dto, options), ct);
};
c.Serializer.RequestDeserializer = async (req, tDto, jCtx, ct) =>
{
using var reader = new StreamReader(req.Body);
return JsonSerializer.Deserialize(await reader.ReadToEndAsync(), tDto, options);
};
});

数据

public static async Task<FileStreamResult?> DownloadBlobAsync(string blobFileName , IConfiguration configuration)
{
string connectionString = configuration.GetSection("Azure").GetValue<string>("BlobConnectionString")!;
string containerName = configuration.GetSection("Azure").GetValue<string>("BlobContainerName")!;

BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);

BlobClient blobClient = containerClient.GetBlobClient(blobFileName);

BlobDownloadInfo download = await blobClient.DownloadAsync();
Stream stream = download.Content;

var contentType = download.ContentType;

return new FileStreamResult(stream, contentType)
{
FileDownloadName = blobFileName
};
}
}

关于c# - 如何将 azure blob 存储文件作为 FileStreamResult 返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76462212/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com