如何返回在ASP.NET Core中存储为byte []的文件?

我已经搜索了一段时间,尽管它应该很简单,但我无法使其正常工作。根据我所看到的示例,这是我到目前为止所掌握的:

SomeAppService.cs

public async Task<FileStream> Download(long? id)
{
    var attachment = await _repository.FirstOrDefaultAsync(x => x.Id == id);

    var fileStream = new FileStream($"{attachment.FileName}.{attachment.FileExtension}",FileMode.Create,Fileaccess.Write);
    fileStream.Write(attachment.File,attachment.File.Length);

    return fileStream;
}

可以注意到,“ FileName”,“ FileExtension”和“ File”(前面提到的字节数组)存储在数据库中。附件可以是任何类型的文件,但Upload方法中的扩展名除外(未显示)。然后在我的控制器中,我有:

SomeController.cs

[AllowAnonymous]
[HttpGet("Download/{id}")]
public async Task<IactionResult> Download(long? id)
{
    var fileStream = await appService.Download(id);
    return new FileStreamResult(fileStream,"application/octet-stream");
}

但是,当我点击下载端点时,最终得到的文件名为“ response”,无扩展名,字节数为0。

资源:

Return file in ASP.Net Core Web API

Return a FileResult from a byte[]

Save and load MemoryStream to/from a file(响应为255次投票使我对如何将字节数组转换为文件流有了想法,但我不知道这样是否可行)

liutongyanjss 回答:如何返回在ASP.NET Core中存储为byte []的文件?

谢谢大家,最终FileContentResult做到了。

这是它的外观:

服务

public async Task<Attachment> Download(long? id)
{
    return await _repository.FirstOrDefaultAsync(x => x.Id == id);
}

控制器

[AllowAnonymous]
[HttpGet("Download/{id}")]
public async Task<IActionResult> Download(long? id)
{
    var attachment = await appService.Download(id);
    return new FileContentResult(attachment.File,MimeTypeMap.GetMimeType(attachment.FileExtension))
    {
        FileDownloadName = $"{attachment.NomeFile}.{attachment.FileExtension}"
    };
}

MimeTypeMap被发现here

,

如果要从实体框架的数据库blob中流式传输文件而不将其加载到内存中。首先将数据模型分为两部分;

public class Attachment{
    public int Id { get; set; }
    public string Filename { get; set; }
    public string ContentType { get; set; }
    public virtual AttachmentBlob Blob { get; set; }
    //...
}

public class AttachmentBlob{
    public int Id { get; set; }
    public byte[] File { get; set; }
}

将它们映射到同一表,但不作为拥有的类型;

   modelBuilder.Entity<Attachment>(e => {
       e.HasOne(a => a.Blob)
        .WithOne()
        .HasForeignKey<AttachmentBlob>(b => b.Id);
   });
   modelBuilder.Entity<AttachmentBlob>(e => {
       e.ToTable("Attachment");
   });

然后,您可以将它们读取或写入为字节数组或流;

   public static async Task Read(DbContext db,Attachment attachment,Func<Stream,Task> callback)
   {
      await db.Database.OpenConnectionAsync();
      try {
         var conn = db.Database.GetDbConnection();
         var cmd = conn.CreateCommand();
         var parm = cmd.CreateParameter();
         cmd.Parameters.Add(parm);
         parm.ParameterName = "@id";
         parm.Value = attachment.Id;
         cmd.CommandText = "select File from Attachment where Id = @id";
         using (var reader = await cmd.ExecuteReaderAsync()){
            if (await reader.ReadAsync())
               await callback(reader.GetStream(0));
         }
      } finally {
         await db.Database.CloseConnectionAsync();
      }
   }

   public class AttachmentResult : FileStreamResult
   {
      private readonly DbContext db;
      private readonly Attachment attachment;

      public AttachmentResult(DbContext db,Attachment attachment) : base(new MemoryStream(),attachment.ContentType)
      {
         this.db = db;
         this.attachment = attachment;
      }

      public override async Task ExecuteResultAsync(ActionContext context)
      {
         await Read(db,attachment,async s => {
            FileStream = s;
            await base.ExecuteResultAsync(context);
         });
      }
   }

   public static async Task Write(DbContext db,Stream content)
   {
      await db.Database.OpenConnectionAsync();
      try {
         var conn = db.Database.GetDbConnection();
         var cmd = conn.CreateCommand();
         cmd.Transaction = db.Database.CurrentTransaction?.GetDbTransaction();
         var parm = cmd.CreateParameter();
         cmd.Parameters.Add(parm);
         parm.ParameterName = "@id";
         parm.Value = attachment.Id;
         parm = cmd.CreateParameter();
         cmd.Parameters.Add(parm);
         parm.ParameterName = "@content";
         parm.Value = content;
         cmd.CommandText = "update Attachment set File = @content where Id = @id";
         await cmd.ExecuteNonQueryAsync();
      } finally {
         await db.Database.CloseConnectionAsync();
      }
   }

   public static Task InsertAttachment(DbContext db,Stream content){
      var strat = db.Database.CreateExecutionStrategy();
      return strat.ExecuteAsync(async () => {
         using (var trans = await db.Database.BeginTransactionAsync())
         {
             db.Set<Attachment>.Add(attachment);
             await db.SaveChangesAsync();
             await Write(db,content);
             trans.Commit();
             db.ChangeTracker.AcceptAllChanges();
         }
      });
   }
本文链接:https://www.f2er.com/2681074.html

大家都在问