大きなファイルで作業する必要があるファイルアップロードAPIを設計しています。私は、バイト配列の回りを離れていたい。ファイルのエンドポイントストレージは、AzureまたはRackspaceファイルストレージなどの第三者になります。ASP.NETコア - ビジネスドメインレイヤーを使用してファイルストリームとバッファーをアップロードする
私はDDD、次のされて、次のプロジェクト構造、している:
- ウェブAPI - ファイルを保存するためのAzureへ
- ビジネスサービス(コール(Netcoreは、アップロードされたファイルを受け入れる)とに記録が保存されますデータベース)
- EF用のドメイン(ドメインモデル)
- 持続性(リポジトリ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 };
}
}
}
そして、何を必要とするものであることをやって大丈夫なら
このファイルには正確に処理が必要ですか?この処理では、そのファイルを完全に読み取る必要がありますか? – Evk
@Evkいいえ、私たちが使用するファイルストレージプロバイダに渡すだけで済みます。たとえば、Rackspace Cloudファイルには、 'cloudFiles.CreateObject(containerName、stream、fileUri);'というメソッドがあります。 Azure Blobストレージには 'blockBlob.UploadFromStream(fileStream);'というメソッドがあります。 – Junto
しかし、あなたは「ファイルはまずビジネスレイヤーで何らかの処理が必要です」と言っていますか? – Evk