john
john

Reputation: 1557

Post large files to REST Endpoint c# .net core

I need to post large files in chunks to an external API. The files type is an MP4 that I have downloaded to my local system and they can be up to 4 gig in size. I need to chunk this data and send it out. Everything I looked at deals with the posting from a Web front end (Angular, JS, etc) and handling the chunked data on the controller. I need to take the file that I have saved local and chunk it up and send it off to an existing API that is expecting chunked data.

Thanks

Upvotes: 2

Views: 4509

Answers (1)

Zinov
Zinov

Reputation: 4119

I think these 2 links can help you to achieve what you need, normally the IFormFile has restrictions for big files, in this case, you need to stream it.

This is from MVC 2 and will help you to understand the HttpPostedFileBase approach

Same approach but wrapping it into a class

Asp.net core 2.2 has the correct example on the documentation in case you want to upload bigger files : See this section

The idea behind is to stream the content, for that, you need to disable the bindings that Asp.net core has and start streaming the content that was posted/uploaded. After you receive that information, then you use the FormValueProvider to rebind all the key/value you received from the client. Because you are using multipart content type, you need to be aware that all the content will not come in the same order, maybe you receive the file, later other parameters or vice-versa.

    [HttpPost(Name = "CreateDocumentForApplication")]
    [DisableFormValueModelBinding]
    public async Task<IActionResult> CreateDocumentForApplication(Guid tenantId, Guid applicationId, DocumentForCreationDto docForCreationDto, [FromHeader(Name = "Accept")] string mediaType)
    {
         //use here the code of the asp.net core documentation on the Upload method to read the file and save it, also get your model correctly after the binding
    }

you can notice that I am passing more parameters as part of the post like DocumentForCreationDto, but the approach is the same(disable the binding)

 public class DocumentForCreationDto : IDto
    {
        //public string CreatedBy { get; set; }
        public string DocumentName { get; set; }
        public string MimeType { get; set; }
        public ICollection<DocumentTagInfoForCreationDto> Tags { get; set; }
    }

If you want to use the postman, see how I am passing the paremeters:

enter image description here

If you want to upload it via code here is the pseudocode:

    void Upload()
    {
        var content = new MultipartFormDataContent();
        // Add the file
        var fileContent = new ByteArrayContent(file);
        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                FileName = fileName,
                FileNameStar = "file"
            };
content.Add(fileContent);
            //this is the way to add more content to the post
            content.Add(new StringContent(documentUploadDto.DocumentName), "DocumentName");
            var url = "myapi.com/api/documents";
            HttpResponseMessage response = null;
            try
            {
                response = await _httpClient.PostAsync(url, content);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
    }

Hope this helps

Upvotes: 2

Related Questions