1

大きなファイルで作業する必要があるファイルアップロードAPIを設計しています。私は、バイト配列の回りを離れていたい。ファイルのエンドポイントストレージは、AzureまたはRackspaceファイルストレージなどの第三者になります。ASP.NETコア - ビジネスドメインレイヤーを使用してファイルストリームとバッファーをアップロードする

私はDDD、次のされて、次のプロジェクト構造、している:

  1. ウェブAPI - ファイルを保存するためのAzureへ
  2. ビジネスサービス(コール(Netcoreは、アップロードされたファイルを受け入れる)とに記録が保存されますデータベース)
  3. EF用のドメイン(ドメインモデル)
  4. 持続性(リポジトリEFCore - データベースの変更を保存します)

私はアップロードが始まるとすぐに、アップロードされたファイルストリームを通過できるメソッドをそれぞれ持っていたいと思います。これが可能かどうかわかりませんか?

以前はレイヤーでファイルを渡すためにbyte []を使用しましたが、大きなファイルの場合は、これに多大なメモリが必要になり、問題が発生しました。

ntierアプリケーションを使用してファイルのアップロードを最適化することは可能ですか?大きいバイト配列をコピーする必要はありません。どうすればできますか?

明確にするために、コード構造は次のようなものになります。リポジトリのものは除外されました:

namespace Project.Controllers 
{ 
    [Produces("application/json")] 
    [Route("api/{versionMNumber}/")] 
    public class DocumentController : Controller 
    { 
     private readonly IAddDocumentCommand addDocumentCommand; 

     public DocumentController(IAddDocumentCommand addDocumentCommand) 
     { 
      this.addDocumentCommand = addDocumentCommand; 
     } 

     [Microsoft.AspNetCore.Mvc.HttpPost("application/{applicationId}/documents", Name = "PostDocument")] 
     public IActionResult UploadDocument([FromRoute] string applicationId) 
     { 
      var addDocumentRequest = new AddDocumentRequest(); 
      addDocumentRequest.ApplicationId = applicationId; 
      addDocumentRequest.FileStream = this.Request.Body; 

      var result = new UploadDocumentResponse { DocumentId = this.addDocumentCommand.Execute(addDocumentRequest).DocumentId }; 

      return this.Ok(result); 
     } 
    } 
} 

namespace Project.BusinessProcess 
{ 
    public interface IAddDocumentCommand 
    { 
     AddDocumentResponse Execute(AddDocumentRequest request); 
    } 

    public class AddDocumentRequest 
    { 
     public string ApplicationId { get; set; } 
     public Stream FileStream { get; set; } 
    } 

    public class AddDocumentResponse 
    { 
     public Guid DocumentId { get; set; } 
    } 

    public class AddDocumentCommand : IAddDocumentCommand 
    { 
     private readonly IDocuentRepository documentRepository; 
     private readonly IMessageBus bus; 

     public AddDocumentCommand(IDocumentRepository documentRepository, IMessageBus bus) 
     { 
      this.documentRepository = documentRepository; 
      this.bus = bus; 
     } 

     public AddDocumentResponse Execute(AddDocumentRequest request) 
     { 
      /// We need the file to be streamed off somewhere else, fileshare, Azure, Rackspace etc 
      /// We need to save a record to the db that the file has been saved successfully 
      /// We need to trigger the background workers to process the uploaded file 

      var fileUri = AzureStorageProvider.Save(request.FileStream); 
      var documentId = documentRepository.Add(new Document { FileUri = fileUri }); 
      bus.AddMessage(new DocumentProcessingRequest { documentId = documentId, fileUri = fileUri }); 

      return new AddDocumentResponse { DocumentId = documentId }; 
     } 
    } 
} 
+0

そして、何を必要とするものであることをやって大丈夫なら

  • このファイルには正確に処理が必要ですか?この処理では、そのファイルを完全に読み取る必要がありますか? – Evk

  • +0

    @Evkいいえ、私たちが使用するファイルストレージプロバイダに渡すだけで済みます。たとえば、Rackspace Cloudファイルには、 'cloudFiles.CreateObject(containerName、stream、fileUri);'というメソッドがあります。 Azure Blobストレージには 'blockBlob.UploadFromStream(fileStream);'というメソッドがあります。 – Junto

    +0

    しかし、あなたは「ファイルはまずビジネスレイヤーで何らかの処理が必要です」と言っていますか? – Evk

    答えて

    0

    いくつかの注意:

    1. は、データをコピーしないバイト配列またはストリームの周りに渡す - 問題がすべてで、サーバー上のデータを持っています。 Webサーバーが完全な形式でデータを処理する必要がある場合は、そのようなメモリー使用を避けることはできません。

    2. Webサーバー上のデータを処理する必要はありませんが、BLOBストレージに格納する必要がある場合は、BLOBストレージを指すアップロード用のURIを返す必要があります役立つ:Using CORS with Azure)は、データを処理する必要がありますが、ビットで-時、この答えのようなものは、あなたがUsing streams in ASP.Net web API

    関連する問題