1

dotnet core web apiのアクションからzipファイルをダウンロードしようとしていますが、動作させることができません。私はPOSTMANとAurelia Http Fetch Clientを介してアクションを呼び出そうとしました。dotnet core webapiからZipFileをダウンロードするには?

私はZipFileを作成してシステムに保存することができますが、それを修正することはできないため、APIを介してzipファイルが返されます。

ユースケース:ユーザーが画像コレクションをいくつか選択し、ダウンロードボタンをクリックします。ピクチャコレクションのIDはapiに送信され、ピクチャを保持するすべてのピクチャコレクションのディレクトリを含むzipファイルが作成されます。そのzipファイルはユーザに返され、システムに保存することができます。

ご協力いただければ幸いです。私が試したものがないことを私が試した何

/** 
* Downloads all pictures from the picture collections in the ids array 
* @params ids The ids of the picture collections to download 
*/ 
download(ids: Array<number>): Promise<any> { 
    return this.http.fetch(AppConfiguration.baseUrl + this.controller + 'download', { 
     method: 'POST', 
     body: json(ids) 
    }) 
} 

注:

私のコントローラのアクション

マイアウレリア

 /// <summary> 
     /// Downloads a collection of picture collections and their pictures 
     /// </summary> 
     /// <param name="ids">The ids of the collections to download</param> 
     /// <returns></returns> 
     [HttpPost("download")] 
     [ProducesResponseType(typeof(void), (int) HttpStatusCode.OK)] 
     public async Task<IActionResult> Download([FromBody] IEnumerable<int> ids) 
     { 
      // Create new zipfile 
      var zipFile = $"{_ApiSettings.Pictures.AbsolutePath}/collections_download_{Guid.NewGuid().ToString("N").Substring(0,5)}.zip"; 

      using (var repo = new PictureCollectionsRepository()) 
      using (var picturesRepo = new PicturesRepository()) 
      using (var archive = ZipFile.Open(zipFile, ZipArchiveMode.Create)) 
      { 
       foreach (var id in ids) 
       { 
        // Fetch collection and pictures 
        var collection = await repo.Get(id); 
        var pictures = await picturesRepo 
          .GetAll() 
          .Where(x => x.CollectionId == collection.Id) 
          .ToListAsync(); 

        // Create collection directory IMPORTANT: the trailing slash 
        var directory = $"{collection.Number}_{collection.Name}_{collection.Date:yyyy-MM-dd}/"; 
        archive.CreateEntry(directory); 

        // Add the pictures to the current collection directory 
        pictures.ForEach(x => archive.CreateEntryFromFile(x.FilePath, $"{directory}/{x.FileName}")); 
       } 
      } 

      // What to do here so it returns the just created zip file? 
     } 
} 
は、クライアント機能をフェッチエラーを生成しない、それはちょうど見えない 何をするにも。

1)自分のFileResultを作成する(以前のASP.NETと同じように)。郵便配達員や申請書を使って電話をしても、使用されているヘッダーはまったく見えません。

return new FileResult(zipFile, Path.GetFileName(zipFile), "application/zip"); 

public class FileResult : IActionResult 
{ 
     private readonly string _filePath; 
     private readonly string _contentType; 
     private readonly string _fileName; 

     public FileResult(string filePath, string fileName = "", string contentType = null) 
     { 
      if (filePath == null) throw new ArgumentNullException(nameof(filePath)); 

      _filePath = filePath; 
      _contentType = contentType; 
      _fileName = fileName; 
     } 

     public Task ExecuteResultAsync(ActionContext context) 
     { 
      var response = new HttpResponseMessage(HttpStatusCode.OK) 
      { 
       Content = new ByteArrayContent(System.IO.File.ReadAllBytes(_filePath)) 
      }; 

      if (!string.IsNullOrEmpty(_fileName)) 
       response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
       { 
        FileName = _fileName 
       }; 

      response.Content.Headers.ContentType = new MediaTypeHeaderValue(_contentType); 

      return Task.FromResult(response); 
     } 
} 

}

2)https://stackoverflow.com/a/34857134/2477872

は何もしません。

 HttpContext.Response.ContentType = "application/zip"; 
      var result = new FileContentResult(System.IO.File.ReadAllBytes(zipFile), "application/zip") 
      { 
       FileDownloadName = Path.GetFileName(zipFile) 
      }; 
      return result; 

私はテストダミーのPDFファイルで試してみましたが、これはPOSTMANで動作するようでした。しかし、私がzipファイルに変更しようとすると(上記参照)、何もしません。長い話を短くを入れて

HttpContext.Response.ContentType = "application/pdf"; 
      var result = new FileContentResult(System.IO.File.ReadAllBytes("THE PATH/test.pdf"), "application/pdf") 
      { 
       FileDownloadName = "test.pdf" 
      }; 

      return result; 

答えて

5

、以下の例では、簡単にDOTNETコアAPIを使用してPDFだけでなく、ZIPの両方にサービスを提供する方法を示しています。

/// <summary> 
/// Serves a file as PDF. 
/// </summary> 
[HttpGet, Route("{filename}/pdf", Name = "GetPdfFile")] 
public IActionResult GetPdfFile(string filename) 
{ 
    const string contentType = "application/pdf"; 
    HttpContext.Response.ContentType = contentType; 
    var result = new FileContentResult(System.IO.File.ReadAllBytes(@"{path_to_files}\file.pdf"), contentType) 
    { 
     FileDownloadName = $"{filename}.pdf" 
    }; 

    return result; 
} 

/// <summary> 
/// Serves a file as ZIP. 
/// </summary> 
[HttpGet, Route("{filename}/zip", Name = "GetZipFile")] 
public IActionResult GetZipFile(string filename) 
{ 
    const string contentType ="application/zip"; 
    HttpContext.Response.ContentType = contentType; 
    var result = new FileContentResult(System.IO.File.ReadAllBytes(@"{path_to_files}\file.zip"), contentType) 
    { 
     FileDownloadName = $"{filename}.zip" 
    }; 

    return result; 
} 

このサンプルでは、​​単に™

の作品

この場合、2つのアクション(ソースファイル名から派生したもの)の主な違いは、返されるcontentTypeだけです。

上記の例ではあなた自身で述べたように 'application/zip'を使用していますが、別のMIMEタイプ( 'application/octet *'など)を提供する必要があるかもしれません。

これは、zipファイルを正しく読み取れないことや、.zipファイルを提供するためにWebサーバーの設定が正しく構成されていない可能性があることを示しています。

後者は、IIS Express、IIS、kestrelなどを実行しているかどうかによって異なる場合がありますが、これをテストに入れるには、〜/ wwwrootフォルダにzipファイルを追加して、ファイルを直接ダウンロードできるかどうかは、Status.csの静的ファイルを参照してください。

関連する問題