Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET核心-通过业务域层上载文件流和缓冲区_C#_Asp.net Core_Asp.net Core Webapi_N Tier Architecture - Fatal编程技术网

C# ASP.NET核心-通过业务域层上载文件流和缓冲区

C# ASP.NET核心-通过业务域层上载文件流和缓冲区,c#,asp.net-core,asp.net-core-webapi,n-tier-architecture,C#,Asp.net Core,Asp.net Core Webapi,N Tier Architecture,我正在设计一个需要处理大文件的文件上传API。我不想传递字节数组。文件的端点存储将是第三方,如Azure或Rackspace文件存储 我有以下项目结构,即DDD: Web API(Netcore-接受上载的文件) 业务服务(调用Azure以保存文件并将记录保存到数据库) 域(EF的域模型) 持久性(存储库EFCore-保存数据库更改) 我希望每个文件中都有方法,可以在上传开始时就开始通过上传的文件流。我不确定这是否可行 以前,我们使用byte[]将文件传递到各个层,但对于大型文件,这似乎需要大量

我正在设计一个需要处理大文件的文件上传API。我不想传递字节数组。文件的端点存储将是第三方,如Azure或Rackspace文件存储

我有以下项目结构,即DDD:

  • Web API(Netcore-接受上载的文件)
  • 业务服务(调用Azure以保存文件并将记录保存到数据库)
  • 域(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 };
            }
        }
    }
    
    一些注意事项:

  • 传递字节数组或流不会复制数据-问题在于数据是否存在于服务器上。如果您的web服务器需要以完整的形式处理数据,您将无法避免这样做的内存使用

  • 如果您根本不需要在web服务器上处理数据,而只需要将其放入blob存储中,那么应该为上载返回一个uri,该uri指向blob存储(这可能会有帮助:)

  • 如果你需要处理数据,但你可以一次处理一点,像这样的答案就是你需要的


  • 这个文件需要什么样的处理?此处理是否涉及完全读取该文件?@Evk否,我只需要将其传递给我们使用的文件存储提供商。例如,Rackspace云文件的方法是:“cloudFiles.CreateObject(containerName、stream、fileUri);”Azure Blob存储的方法是“blockBlob.UploadFromStream(fileStream);”但是你说“但是文件需要先在我们的业务层进行一些处理”?编辑之后,我仍然不清楚是什么问题。您可以在示例中的层之间传递
    ,就像您希望的那样。它不能像你期望的那样工作,或者什么?基本上你需要流式处理文件,尽管我想这确实限制了你“处理”它的能力。这里有一些信息